プログラミングやWebアプリケーションで、データをテキストファイルやCSVなどで管理することは、実際の現場ではほぼないだろう。

多くの場合はデータベースを使用して、データの保存・参照をおこなうはずだ。

データベースにはSQLServer、PostgreSQL、MySQLなど、多くの種類が存在するが、今回はPythonで手軽に利用できるSQLiteを使って簡単な例を紹介していく。

sqlite3ドライバを使ってSQLiteデータベースを作成する

まずはPython組み込みのsqlite3ドライバを使って、データベースを作成する。

import sqlite3

q = """
create table test
(
    a VARCHAR(20), b VARCHAR(20), c INTEGER, d REAL
);
"""
con = sqlite3.connect('mydata.sqlite')
con.execute(q)

ここまで準備できたらコミット処理をおこなう。

con.commit()

これで、testというテーブルが作成された。

次に作成したテーブルに適当なデータを数行挿入する。

data= [
    ('Yamada', 'Taro', 15, 152.8),
    ('Tanaka', 'Jiro', 16, 168.9),
    ('Suzuki', 'Saburo', 18, 167.3)
]

stmt = "INSERT INTO test VALUES(?,?,?,?)"

con.executemany(stmt, data)

変数dataに挿入するデータをリストとして保存し、stmtにSQL文を用意する。
executemanyメソッドでINSERT文を実行。

最後にコミット処理をおこなう。

con.commit()

これでテスト用のデータベースが完成した。

データベースを読み込む

cursor = con.execute('SELECT * FROM test')
rows = cursor.fetchall()

rows
# [('Yamada', 'Taro', 15, 152.8),
#  ('Tanaka', 'Jiro', 16, 168.9),
#  ('Suzuki', 'Saburo', 18, 167.3)]

SELECT文を実行して取得したデータを確認してみると、先ほど用意したデータ一覧が取得できていることが分かる。

読み込んだデータをpandasデータフレームに変換する

取得したデータ(タプルのリスト)をpandasデータフレームに変換する場合、データと合わせて列名もコンストラクタに渡す必要がある。

列名は下記のとおり、descriptionメソッドで取得できる。

cursor.description
# (('a', None, None, None, None, None, None),
#  ('b', None, None, None, None, None, None),
#  ('c', None, None, None, None, None, None),
#  ('d', None, None, None, None, None, None))

これを利用して、pandasデータフレームに変換する。

import pandas as pd

df = pd.DataFrame(rows, columns=[x[0] for x in cursor.description])
#         a       b   c      d
# 0  Yamada    Taro  15  152.8
# 1  Tanaka    Jiro  16  168.9
# 2  Suzuki  Saburo  18  167.3

もっと簡単にデータを読み込むread_sql

先述のデータフレームへの変換は面倒な手順を挟むため、pandasではより簡単にデータを取得できるread_sqlという関数が用意されている。

以下は、データベースにSQLAlchemyで接続して、テーブルからデータを読み込む例だ。

import sqlalchemy as sqla

db = sqla.create_engine('sqlite:///mydata.sqlite')

pd.read_sql('SELECT * FROM test', db)
#         a       b   c      d
# 0  Yamada    Taro  15  152.8
# 1  Tanaka    Jiro  16  168.9
# 2  Suzuki  Saburo  18  167.3

コード量が圧倒的に少なくなり、かなり扱いやすくなった。