pandas で SQL データベースと連携する(read_sql / to_sql)

pandas は SQL データベースとの連携機能を備えており、SQL を書いてデータを取得したり、DataFrame をテーブルに書き込んだりできます。データベース上のデータをそのまま Python で分析したい場面で役立つ機能です。

SQLAlchemy でデータベースに接続する

pandas の SQL 関連関数は、内部で SQLAlchemy のエンジンを利用します。まずは接続用のエンジンを作成しましょう。

from sqlalchemy import create_engine

engine = create_engine("sqlite:///sample.db")

SQLite のほか、PostgreSQL や MySQL にも対応しています。接続文字列の形式はデータベースごとに異なりますが、基本的な使い方は同じです。

SQLitesqlite:///ファイルパス
PostgreSQLpostgresql://user:pass@host/db
MySQLmysql+pymysql://user:pass@host/db

read_sql でデータを取得する

SQL クエリを文字列で渡すと、結果が DataFrame として返されます。

import pandas as pd

df = pd.read_sql("SELECT * FROM users WHERE age >= 20", engine)
print(df)

SQL の集計関数や結合もそのまま使えるため、データベース側で絞り込みや前処理を済ませてから Python に持ってくることが可能です。大量のデータを全件読み込むよりも効率的でしょう。

read_sql_table でテーブル全体を読み込む

特定のテーブルを丸ごと読み込むなら read_sql_table が簡潔です。

df = pd.read_sql_table("users", engine)

SQL を書く必要がなく、テーブル名を指定するだけで済みます。ただし大きなテーブルの場合はメモリに注意してください。

to_sql でデータベースに書き込む

DataFrame をテーブルとして保存するには to_sql を使います。

df = pd.DataFrame({
    "name": ["Alice", "Bob", "Charlie"],
    "age": [25, 30, 35],
    "score": [88.5, 92.0, 76.3]
})
df.to_sql("results", engine, if_exists="replace", index=False)

if_exists 引数で、テーブルがすでに存在する場合の挙動を制御できます。

if_exists="fail"

テーブルが存在するとエラーを発生させる。デフォルトの挙動

if_exists="replace"

既存テーブルを削除してから新規作成する

if_exists=“append” を指定すれば、既存テーブルにデータを追記することも可能です。index=False を忘れると、DataFrame のインデックスが余計な列として追加されてしまうので注意しましょう。

chunksize で分割書き込みする

データ量が大きい場合は、chunksize 引数を指定して分割書き込みできます。

df.to_sql("results", engine, if_exists="append", index=False, chunksize=1000)

1000 行ずつデータベースに送信するため、メモリの消費を抑えられます。読み込み側の read_sql でも chunksize を指定すれば、イテレータとして少しずつ取得することが可能です。

pandas と SQL データベースの組み合わせは、既存の業務データベースから分析用のデータを引き出すワークフローで特に威力を発揮します。SQL でできる処理はデータベース側に任せ、pandas では加工や可視化に集中するのが効率的な使い分けです。