ライブラリ

データベースの使い方(SQLite)

データベースSQLite

データ解析や機械学習をする場合はデータの蓄積が必要になりますが、それを簡単に行えるのがSQLiteの魅力です。

SQLiteは軽量データベースの一つで、Pythonの標準ライブラリとして準備されています。

ここでは「SQLiteって何?」「どうやって使うの?」「データを登録したり取り出したりしてみたい」といった方へ、SQLiteの使い方を解説します。

SQLiteの使い方

実際にSQLiteを使ってみましょう。ここではデータベースの作成やテーブルの作成、データの登録・更新・削除・参照といった処理を解説します。

データベースの作成とカーソルの取得

connect()の引数にデータファイル名を渡すことで、データベースを作成できます。

既に存在するデータベースの場合は単純に接続するだけ、新しいデータベースの場合はデータを保存するためのデータファイルを作成します。

import sqlite3
db = sqlite3.connect('example.db')
c = db.cursor()

今回はexample.dbというデータファイルを作成しました。connect()の戻り値はconnectionオブジェクトが返却され、これがデータベースを表しています。

また、db作成後にcursor()を呼び出しています。このカーソルはデータベース技術の一つで、検索結果からデータを処理するための仕組みです。

テーブルを作成する

まずはデータを格納するためのテーブルを作成しましょう。SQLを実行するにはCorsorオブジェクトのexecute()を使います。

c.execute('CREATE TABLE user(id integer, name text)')
c.close() #最後にカーソルを閉じる

※データベースの作成とカーソルの取得までは全て共通なので省略します

上記の例ではuserというテーブルを作成しました。作成したテーブルやデータはデータファイルに保存されるので、上記のコードを2回実行すると「既にuserテーブルは存在している」というエラーになります。

データを登録する

データを登録する場合も同じくexecute()を使います。

ただし、テーブル作成と違いINSERTはDML(データ操作言語)なので、コミット処理が必要になります(これをしないとデータが登録されません)。

コミット処理はConnectionオブジェクトのcommit()を使います。

c.execute('INSERT INTO user VALUES(1, "user_1")')
db.commit() #これが必要
c.close()

データを複数行同時に登録する

execute()で1件ずつデータを登録するのも良いですが、executemany()を使うことでより簡潔に複数行のデータを登録できます。

data = [
    (2, 'user_2'),
    (3, 'user_3'),
    (4, 'user_4'),
    (5, 'user_5'),
]
c.executemany('INSERT INTO user VALUES(?, ?)', data)
db.commit()
c.close()

登録したデータを参照する

実際にデータが登録されているかを確認してみましょう。

SELECTで取得したデータを取り出すにはfetchall()を使います。

r = c.execute('SELECT * FROM user')
print(r.fetchall())

[出力結果]

[(1, 'user_1'), (2, 'user_2'), (3, 'user_3'), (4, 'user_4'), (5, 'user_5')]

fetchall()で取得したデータはタプルのリスト形式で返却されます。

また、forを使えばfetchall()を使わずに取得したデータにアクセスできます。

c.execute('SELECT * FROM user')
for row in c:
    print(row[0], row[1])

[出力結果]

1 user_1
2 user_2
3 user_3
4 user_4
5 user_5

カラム名でデータを取得したい場合

上記の例ではデータがタプルで返ってくるため、row[0]のようにインデックス番号を指定する必要がありました。

これだとどのカラムを参照しているのか分かりづらいので、カラム名で取り出せるように変更してみましょう。

db = sqlite3.connect('example.db')
db.row_factory = sqlite3.Row #これが必要
c = db.cursor()
c.execute('SELECT * FROM user')
for row in c:
    print(row['id'], row['name'])

[出力結果]

1 user_1
2 user_2
3 user_3
4 user_4
5 user_5

sqlite3.Rowオブジェクトをdbのrow_factoryに設定することで、SELECTの結果をカラム名で取得できるようになります。

データの更新と削除

登録されているデータを更新したり、削除する場合は、登録のときと同じくexecute()を使います。

import sqlite3

def print_user_table(c):
    c.execute('SELECT * FROM user')
    for row in c:
        print(row['id'], row['name'])

db = sqlite3.connect('example.db')
db.row_factory = sqlite3.Row
c = db.cursor()
print("更新前")
print_user_table(c)
c.execute('UPDATE user SET name = "update_user" WHERE id = 2') #更新
c.execute('DELETE FROM user WHERE id = 4') #削除
db.commit()
print("更新後")
print_user_table(c)
c.close()

[出力結果]

更新前
1 user_1
2 user_2
3 user_3
4 user_4
5 user_5
更新後
1 user_1
2 update_user
3 user_3
5 user_5

上記の例ではidが2のユーザのnameを「update_user」に変更し、idが4のユーザを削除しています。

SQLiteのエラー処理

一意キーエラーや外部参照エラーなど、データベース処理にエラーはつきものです。データベースとやり取りをする時は基本的にtry〜exceptで例外処理を入れておきましょう。

SQLiteのエラー内容はsqlite3.errorから取得できます。

db = sqlite3.connect('example.db')
db.row_factory = sqlite3.Row
c = db.cursor()

try:
    c.execute('CREATE TABLE user(id integer, name text)') #すでに作成されているテーブルを作成しようとしてます
except sqlite3.Error as e:
    print('SQLite Error : ' + e.args[0])
c.close()

[出力結果]

SQLite Error : table user already exists

userテーブルはすでに作成されているので、table user already existsが返却されました。

タイトルとURLをコピーしました