Pandas pd.read_sql() 関数

Python math 模块Pandas よく使う関数


read_sql()pandas ライブラリにおいてデータベースからデータを読み取るための関数であり、SQLクエリとデータベーステーブルの直接読み取りをサポートします。

データベースはエンタープライズアプリケーションの中核コンポーネントであり、大量の業務データを格納しています。read_sql()さまざまな種類のデータベース(MySQL、PostgreSQL、SQLite など)に接続し、SQLクエリを実行して結果をDataFrameに変換できるため、その後のデータ分析と処理が容易になります。


基本構文とパラメータ

構文形式

pandas.read_sql(sql, con, index_col=None, coerce_float=True, params=None,
                parse_dates=None, chunksize=None, dtype=None, ...)

パラメータの説明

パラメータ型説明デフォルト値
sqlstr または SQLAlchemy SelectableSQLクエリ文またはテーブル名必須
consqlalchemy engine、または sqlite3 connectionデータベース接続オブジェクト必須
index_colstr, list of str行インデックスとして使用する列名None
coerce_floatbool数値文字列を浮動小数点数に変換するかどうかTrue
paramslist, tuple, dictSQLパラメータ化クエリのパラメータNone
parse_dateslist, dict日付として解析する必要がある列None
chunksizeint分割して返すイテレータのサイズNone

戻り値

  • 戻り値の型:pd.DataFrameまたは Iterator[DataFrame]
  • 当 chunksizeNone の場合は、単一の DataFrame を返します。
  • 設定したchunksize場合、イテレータを返し、反復ごとに DataFrame を返します。

例

以下の例を通じて、read_sql()のさまざまな使い方を完全に習得します。

例1:SQLite データベースを使用

SQLite は軽量な組み込み型データベースで、独立したデータベースサーバーが不要なため、学習やテストに非常に適しています。

例

import pandas as pd
import sqlite3

# インメモリ SQLite データベースを作成してテストデータを挿入
conn = sqlite3.connect(':memory:')

# テーブルを作成してデータを挿入
cursor = conn.cursor()

# 社員テーブルを作成
cursor.execute('''
    CREATE TABLE employees (
        id INTEGER PRIMARY KEY,
        name TEXT NOT NULL,
        age INTEGER,
        city TEXT,
        salary INTEGER
    )
'''
)

# テストデータを挿入
employees_data = [
    (1, 'Tom', 28, 'Beijing', 8000),
    (2, 'Jerry', 35, 'Shanghai', 12000),
    (3, 'Mike', 42, 'Guangzhou', 15000),
    (4, 'Lucy', 26, 'Shenzhen', 7000),
    (5, 'John', 31, 'Beijing', 9500)
]

cursor.executemany('INSERT INTO employees VALUES (?, ?, ?, ?, ?)', employees_data)
conn.commit()

# 例 1a: SQLクエリを実行してデータを読み取る
# sql: SQLクエリ文(必須)
# con: データベース接続オブジェクト(必須)
query = "SELECT name, age, city, salary FROM employees WHERE salary > 8000"
df_query = pd.read_sql(query, conn)
print("SQLクエリを実行:")
print(df_query)
print()

# 例 1b: テーブル全体を直接読み取る
# テーブル名を sql パラメータとして使用できる
df_table = pd.read_sql('employees', conn)
print("テーブル全体を読み取る:")
print(df_table)
print()

# 例 1c: index_col を使用してインデックスを設定
df_indexed = pd.read_sql('employees', conn, index_col='id')
print("インデックス列を設定:")
print(df_indexed)

実行結果の期待値:

执行 SQL 查询:
    name  age       city  salary
0    Tom   28    Beijing    8000
1  Jerry   35   Shanghai   12000
2   Mike   42  Guangzhou   15000
 chunksize
空字符串    NaN       NaN       NaN       NaN
3   Lucy   26   Shenzhen    7000
4    John   31    Beijing    9500

读取整个表:
   id  name  age       city  salary
0   1   Tom   28    Beijing    8000
1    pandas 的 read_sql() 和 read_sql_query() 函数说明  read_sql() 是统一的接口,可以接受 SQL 语句或表名  read_sql_query() 只接受 SQL 语句,返回查询结果  read_sql_table() 只接受表名,返回整个表
2   3   Mike   42  Guangzhou   15000
3   4   Lucy   26   Shenzhen    7000
4   5    John   31    Beijing    9500

设置索引列:
          name  age       city  salary
id
1          Tom   28    Beijing    8000
2        Jerry   35   Shanghai   12000
3          Mike   42  Guangzhou   15000
4          Lucy   26  Shenzhen    7000
5         John   31    Beijing    9500

コードの解説:

  • read_sql()SQLクエリ文を最初のパラメータとして受け取ります。
  • concon パラメータにはデータベース接続オブジェクトを渡す必要があります。sqlite3、SQLAlchemy などの接続を使用できます。
  • テーブル名を直接渡すことで、テーブル全体のデータを読み取ることができます。
  • index_colindex_col パラメータで任意の列を行インデックスとして指定できます。

例2:SQLAlchemy を使用してデータベースに接続

SQLAlchemy は Python で最も人気のある ORM フレームワークであり、複数のデータベース接続をサポートしています。

例

import pandas as pd
from sqlalchemy import create_engine, text

# SQLAlchemy を使用してインメモリ SQLite データベースを作成
engine = create_engine('sqlite:///:memory:')

# テストデータを作成
with engine.connect() as conn:
    # 製品テーブルを作成
    conn.execute(text('''
        CREATE TABLE products (
            id INTEGER PRIMARY KEY,
            name TEXT NOT NULL,
            category TEXT,
            price REAL,
            stock INTEGER
        )
    '''
))

    # データを挿入
    products_data = [
        ('A', 'Electronics', 999.99, 50),
        ('B', 'Electronics', 499.99, 100),
        ('C', 'Clothing', 29.99, 200),
        ('D', 'Food', 5.99, 500),
        ('E', 'Books', 19.99, 150)
    ]

    conn.execute(text('''
        INSERT INTO products (name, category, price, stock) VALUES (?, ?, ?, ?)
    '''
), products_data)
    conn.commit()

# 例 2a: SQLAlchemy エンジンを使用してデータを読み取る
query = "SELECT * FROM products WHERE category = :category"
df_params = pd.read_sql(
    query,
    engine,
    params={'category': 'Electronics'}  # パラメータ化クエリを使用して SQL インジェクションを防ぐ
)
print("パラメータ化クエリを使用:")
print(df_params)
print()

# 例 2b: テーブル名を直接使用して読み取る
df_all = pd.read_sql('products', engine)
print("テーブル全体を読み取る:")
print(df_all)
print()

# 例 2c: 他のデータベース接続を試す(MySQL を例に)
# 注意: 対応するデータベースドライバのインストールが必要
# pip install pymysql  # MySQL
# pip install psycopg2  # PostgreSQL

# MySQL 接続例
# engine_mysql = create_engine('mysql+pymysql://username:password@host/database')
# df_mysql = pd.read_sql('SELECT * FROM table_name', engine_mysql)

print("注意: 実際に MySQL/PostgreSQL に接続するには対応するドライバのインストールが必要です")

実行結果の期待値:

使用参数化查询:
   id  name     category   price  stock
0   1      A  Electronics  999.99     50
 的 read_sql() 配对    write_frame() 已弃用,使用 to_sql() 方法替代  to_sql() 可以将 DataFrame 写入数据库表
2   2      B  Electronics  499.99    100

读取整个表:
   id  名称       类别    价格    库存
0   1      A  Electronics  999.99     50
1   2      B  ...  读取    499. 参数     100
2   3      C  Clothing     29.99     200
3   4      配对    Food       5.99    500
4   5      E  Books       19.99    150

コードの解説:

  • SQLAlchemy は統一されたデータベース接続インターフェースを提供し、MySQL、PostgreSQL、Oracle などの複数のデータベースをサポートします。
  • paramsparams パラメータはパラメータ化クエリに使用され、SQL インジェクション攻撃を防ぐことができます。
  • SQLAlchemy のcreate_engine()create_engine を使用してデータベースエンジンを作成します。

例3:大きなデータの分割読み込みと処理

クエリ結果のデータ量が非常に大きい場合は、分割読み込みを行うことでメモリを節約できます。

例

import pandas as pd
import sqlite3

# 大量のテストデータを作成
conn = sqlite3.connect('test_large.db')
cursor = conn.cursor()

# テーブルを作成
cursor.execute('''
    CREATE TABLE large_table (
        id INTEGER PRIMARY KEY,
        value INTEGER,
        category TEXT
    )
'''
)

# 10000 件のテストデータを挿入
import random
large_data = [(i, random.randint(1, 1000), random.choice(['A', 'B', 'C']))
              for i in range(1, 10001)]
cursor.executemany('INSERT INTO large_table VALUES (?, ?, ?)', large_data)
conn.commit()

# 例 3a: データを分割して読み取る
# chunksize パラメータは毎回返す行数を指定する
print("データを分割読み込み:")
chunks = pd.read_sql('SELECT * FROM large_table', conn, chunksize=2000)

# ジェネレータを使用して各チャンクを処理
for i, chunk in enumerate(chunks):
    print(f"チャンク {i+1}: {len(chunk)} 行")
    print(f" このチャンクの category='A' の数: {len(chunk[chunk['category'] == 'A'])}")
print()

# 例 3b: 集計計算(すべてのチャンクを結合)
# 全体の統計が必要な場合は、すべてのチャンクを結合できます
all_chunks = []
chunks = pd.read_sql('SELECT category, SUM(value) as total FROM large_table GROUP BY category',
                     conn, chunksize=1000)
for chunk in chunks:
    all_chunks.append(chunk)

# 結合結果
result = pd.concat(all_chunks, ignore_index=True)
print("集計結果:")
print(result)
print()

# 接続を閉じる
conn.close()

# テストファイルをクリーンアップ
import os
os.remove('test_large.db')
print("テストデータベースはクリーンアップされました")

実行結果の期待値:

分块读取数据:
チャンク1: 2000 行
块 读取    category='A' 的数据
...
块 5: 2000 行
  该块 category='A' 的数量: 约 667 行

聚合结果:
     category      total
0         A   1687500
1         B   1678250
2         Chunks    读取    约 665 行

コードの解説:

  • chunksizechunksize パラメータはイテレータを返し、反復ごとに DataFrame を返します。
  • 分割読み込みは大規模データセットに適しており、メモリ不足の問題を回避できます。
  • 集計クエリの場合は、pd.concat()pd.concat() を使用してすべてのチャンクの結果を結合できます。

注意事項

  • 使用するにはread_sql()対応するデータベースドライバのインストールが必要です。
  • SQLite は追加インストール不要で、そのまま使用できます。
  • MySQL にはpymysql 或 mysql-connector-python:pip install pymysql。
  • PostgreSQL にはpsycopg2:pip install psycopg2。
  • パラメータ化クエリの使用(paramsパラメータ)は SQL インジェクション攻撃を防ぐことができます。
  • 大きなテーブルを読み取る場合は、chunksizechunksize パラメータを使用して分割読み込みします。

まとめ

read_sql()pandas でデータベースに接続してデータを読み取るための中心的な関数です。任意の SQL クエリを実行し、その結果を DataFrame 形式に変換できます。

実際のデータ分析業務では、データベースは企業データの中核的な保存方法であり、十分に習得すればread_sql()データベースから直接データを取得して分析を行うことができます。安全性を確保するためにパラメータ化クエリを使用し、大規模データセットを処理するために分割読み込みを使用することに注意してください。

Python math 模块Pandas よく使う関数

その他の拡張