SQLite3
前回、データベース管理システムSQLite3でデータが重複したら更新か何もしない、新規のデータは追加する動作を勉強してみました。
前回まででデータベースやテーブルの作成をしたり、データを追加、削除、更新をしたりとSQLite3の基本的な動作に関しては勉強できたと考えています。
ということでそろそろPythonを使ってSQLite3操ってみようと思います。
といっても実際にSQLite3のデータベースをいじくるのはSQLite3のコマンドなので、前回までのSQLite3の勉強が大事だったりします。
それでは始めていきましょう。
データベースの作成と開く・閉じる
まずはデータベースの作成を作成を行います。
そのためにはまずsqlite3のライブラリをインポートする必要があります。
import sqlite3
そしてデータベースを作成するには「sqlite3.connect(データベースへのパス)」です。
作成した後、そのデータベースへの読み書きをするため、変数に格納します。
ということでこんな感じ。
import sqlite3
dbname = 'test7.db'
conn = sqlite3.connect(dbname)
conn.close()
実行結果
実行結果は何も表示されませんが、これで「test7.db」というデータベースが作成されました。
またデータベースを使い終わった後は閉じないとずっと開いたままになり、メモリを圧迫しますので、最後に「conn.close()」でデータベースへのアクセスを閉じています。
ただwith構文を使って「with sqlite3.connect(データベースへのパス) as 変数:」のような書き方も可能です。
import sqlite3
dbname = 'test7.db'
with sqlite3.connect(dbname) as conn:
print('動作を記述')
実行結果
動作を記述
print文は単純に実行してもエラーにならないように書いているだけです。
この書き方には大きなメリットがあるのですが、それは後ほど解説します。
とりあえずこのようにしてデータベースを作成するのですが、データベースを開くときも「sqlite3.connect(データベースへのパス)」です。
つまりデータベースへのパスで指定されているファイルが存在しなければ新規で作成し、存在していたらそのデータベースを開くという挙動を示すわけです。
データベースの操作の仕方
それではPythonでデータベースの操作をしていきます。
データベースの操作をするにはまずカーソルオブジェクトを作成します。
cur = conn.cursor()
カーソルオブジェクトが何なのかは私もよく理解していませんが、このカーソルオブジェクトにコマンドを渡してデータベースを操作するとのことです。
カーソルオブジェクトにコマンドを渡すには「cur.excecute(“SQLite3のコマンド”)」とします。
ということでテーブルを作成し、データを追加してみましょう。
この時に「”(ダブルクオーテーション)」と「’(シングルクオーテーション)」を意識して書き分け、SQLite3のコマンド文全体なのか、その中の文字列なのかをしっかり区別しましょう。
import sqlite3
dbname = 'test7.db'
conn = sqlite3.connect(dbname)
cur = conn.cursor()
cur.execute("CREATE TABLE table1(id INTEGER PRIMARY KEY, name TEXT, age INTEGER)")
cur.execute("INSERT INTO table1(id, name, age) values(1, 'Sato', 10)")
conn.close()
実行結果
このままでは実行結果には何も表示されません。
ということでもう一度データベースにアクセスして、「SELECT文」でデータを取得してみましょう。
import sqlite3
dbname = 'test7.db'
conn = sqlite3.connect(dbname)
cur = conn.cursor()
cur.execute("SELECT * FROM table1")
conn.close()
実行結果
実はこれでも取得したデータは表示されません。
取得したデータをSQLite3からPythonに受け渡す必要があります。
そのためには「cur.fetchall()」を使用します。
import sqlite3
dbname = 'test7.db'
conn = sqlite3.connect(dbname)
cur = conn.cursor()
cur.execute("SELECT * FROM table1")
print(cur.fetchall())
conn.close()
実行結果
[]
「cur.fetchall()」でデータがPythonに渡され、Printで表示されました。
しかし実行結果の表示は「[](空のリスト)」になっています。
どうしてなのでしょうか?
実はテーブルを作成し、データを追加したこちらのプログラムに問題があります。
import sqlite3
dbname = 'test7.db'
conn = sqlite3.connect(dbname)
cur = conn.cursor()
cur.execute("CREATE TABLE table1(id INTEGER PRIMARY KEY, name TEXT, age INTEGER)")
cur.execute("INSERT INTO table1(id, name, age) values(1, 'Sato', 10)")
conn.close()
実はSQLite3をターミナルで使用した時とは違って、データは自動で保存されません。
保存したいタイミングで「conn.commit()」というデータを保存するコマンドを実行する必要があります。
ただテーブルは追加した時点で保存されるようですので、データを再度追加してみましょう。
import sqlite3
dbname = 'test7.db'
conn = sqlite3.connect(dbname)
cur = conn.cursor()
cur.execute("INSERT INTO table1(id, name, age) values(1, 'Sato', 10)")
conn.commit()
conn.close()
実行結果
そして再度データベースの中身を確認してみます。
import sqlite3
dbname = 'test7.db'
conn = sqlite3.connect(dbname)
cur = conn.cursor()
cur.execute("SELECT * FROM table1")
print(cur.fetchall())
conn.close()
実行結果
[(1, 'Sato', 10)]
with構文を使う利点
ここでwith構文を使う利点が出てきます。
with構文を使いファイルを開いた場合には、最後に「f.close()」のように閉じるコマンドを実行する必要がありません。
もちろん今回のSQLite3のデータベースをwith構文で開いた際も「conn.close()」で閉じる必要が無くなります。
そしてもう一つ。
データを追加した際の「conn.commit()」も自動でされるようで、記述する必要が無くなります。
試してみましょう。
import sqlite3
dbname = 'test7.db'
with sqlite3.connect(dbname) as conn:
cur = conn.cursor()
cur.execute("INSERT INTO table1(id, name, age) values(2, 'Suzuki', 15)")
cur.execute("INSERT INTO table1(id, name, age) values(3, 'Takahashi', 20)")
import sqlite3
dbname = 'test7.db'
with sqlite3.connect(dbname) as conn:
cur = conn.cursor()
cur.execute("SELECT * FROM table1")
print(cur.fetchall())
実行結果
[(1, 'Sato', 10), (2, 'Suzuki', 15), (3, 'Takahashi', 20)]
「conn.commit()」をしていないにも関わらずデータが保存されました。
かなり便利なので、今後はこちらの書き方をしていこうと思います。
cur.fetchall()の後のデータの処理
cur.fetchall()でデータが取得できたので、ここからはPythonのプログラムで処理ができるようになります。
ということでまずはcur.fetchall()で取得したデータを変数に格納してみましょう。
import sqlite3
dbname = 'test7.db'
with sqlite3.connect(dbname) as conn:
cur = conn.cursor()
cur.execute("SELECT * FROM table1")
data = cur.fetchall()
print(data)
実行結果
[(1, 'Sato', 10), (2, 'Suzuki', 15), (3, 'Takahashi', 20)]
変数に格納されたデータはリストの中にタプルが入った形式になっています。
そのため取り出すにはインデックスを指定してあげます。
import sqlite3
dbname = 'test7.db'
with sqlite3.connect(dbname) as conn:
cur = conn.cursor()
cur.execute("SELECT * FROM table1")
data = cur.fetchall()
print(data[0][0])
print(data[0][1])
print(data[0][2])
実行結果
1
Sato
10
また1行ずつデータを取り出すにはfor文を使います。
import sqlite3
dbname = 'test7.db'
with sqlite3.connect(dbname) as conn:
cur = conn.cursor()
cur.execute("SELECT * FROM table1")
data = cur.fetchall()
for person in data:
print(person)
実行結果
(1, 'Sato', 10)
(2, 'Suzuki', 15)
(3, 'Takahashi', 20)
これで大体PythonからSQLite3のデータベースを操作することができるようになりました。
ただ今回特に述べませんでしたが、どうやら「.schema」や「.tables」といった最初に「.(ピリオド)」がつくSQLite3のコマンドは使えないようです。
つまりどんなテーブルがあるのかやそのテーブルの構成(列名)に関してはこのままでは取得できません、
ということで次回はPythonでSQLite3のデータベースのテーブル名や列名を取得する方法を勉強していきましょう。
ではでは今回はこんな感じで。
コメント