【Python】PostgreSQL操作の基本:psycopg2での接続とデータ取得

PythonからPostgreSQLデータベースを操作する場合、最も広く利用されているライブラリが psycopg2 です。このライブラリはPostgreSQLの機能を網羅的にサポートしており、高速かつ堅牢です。

特に MySQLdb などの他ドライバと異なる点として、PythonのタプルやリストをSQLの配列や IN 句のリストへ自動的に変換(アダプテーション)する強力な機能を持っています。ここでは、接続設定の管理方法と、リストデータを条件に含むデータの取得方法について解説します。

目次

ライブラリのインストール

開発環境や一般的な用途では、ビルド済みのバイナリが含まれる psycopg2-binary のインストールが推奨されます。

pip install psycopg2-binary

実行可能なサンプルコード

以下のコードは、ECサイトの注文管理システムを想定し、「一定金額以上の注文」かつ「特定の配送地域コードに含まれる」データを抽出するスクリプトです。

psycopg2 の特徴として、SQLの IN 句に対してPythonのタプルをそのままプレースホルダ %s に渡すだけで、自動的にSQL構文として展開される点が挙げられます(文字列操作でプレースホルダを増やす必要がありません)。

import psycopg2
import os

# 接続設定
# 実運用では環境変数や設定ファイルから読み込むことを推奨します
DB_CONFIG = {
    "user": "order_manager",
    "password": "secure_db_password",
    "host": "localhost",
    "port": "5432",
    "dbname": "ec_system"
}

def main():
    # 検索条件
    # 金額が 5000円以上、かつ 地域コードが 'TK', 'OS', 'NG' のいずれか
    min_amount = 5000
    target_regions = ('TK', 'OS', 'NG')

    # SQL文の構築
    # psycopg2では、IN句の中身も単一の %s で表現可能です
    sql = """
        SELECT 
            order_id, 
            customer_name, 
            amount, 
            region_code, 
            order_date
        FROM 
            orders 
        WHERE 
            amount > %s 
            AND region_code IN %s
    """

    print(f"Connecting to database: {DB_CONFIG['dbname']}...")

    try:
        # データベース接続
        # 辞書を展開して引数として渡します
        with psycopg2.connect(**DB_CONFIG) as conn:
            
            # カーソルの取得
            with conn.cursor() as cur:
                
                # SQLの実行
                # 第2引数はタプルで渡します。
                # target_regions(タプル)自体が、2つ目の %s に対応します。
                cur.execute(sql, (min_amount, target_regions))
                
                # 結果の取得
                rows = cur.fetchall()
                
                # 結果の表示
                print(f"\nHit Count: {len(rows)}")
                print("-" * 40)
                
                for row in rows:
                    # rowはタプル (order_id, name, amount, region, date)
                    print(f"ID: {row[0]} | Amount: {row[2]} | Region: {row[3]}")

    except psycopg2.Error as e:
        print(f"Database error: {e.pgcode} - {e.pgerror}")
    except Exception as e:
        print(f"System error: {e}")

if __name__ == "__main__":
    main()

コードのポイント解説

1. 接続パラメータの辞書管理

psycopg2.connect(**DB_CONFIG) のように辞書アンパックを使用することで、コードの可読性が向上します。PostgreSQLのデフォルトポートは 5432 です。

2. コンテキストマネージャ(with構文)

with psycopg2.connect(...) as conn: および with conn.cursor() as cur: を使用することで、処理終了時や例外発生時に自動的に接続やカーソルが閉じられ、リソースリークを防げます。また、connwith ブロックを抜ける際、例外がなければ自動的にトランザクションがコミットされ、例外時はロールバックされます。

3. IN句へのタプル渡し(重要)

MySQLdb など他のドライバでは、リストの要素数分だけ %s, %s, ... とプレースホルダを用意する必要がありますが、psycopg2 はPythonのタプルをSQLのリスト表現 (item1, item2, ...) に自動変換します。

  • SQL側: IN %s (1つのプレースホルダのみ)
  • パラメータ側: (val1, ('A', 'B', 'C'))

このように記述するだけで、内部的に IN ('A', 'B', 'C') というSQLが生成され、非常に効率的かつ安全にクエリを実行できます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次