モジュールの基本的な使用方法#

psycopg の基本的な使用方法は、DB-API プロトコルを実装しているすべてのデータべース アダプターと共通するものです。sqlite3psycopg2 などの他のデータベース アダプターには、おおよそ同じ対話のパターンがあります。

psycopg 3 のメイン オブジェクト#

次に示すのは、基本的なコマンドの一部を表示している対話セッションです。

# メモ: モジュール名は psycopg3 ではなく psycopg
import psycopg

# 既存のデータベースに接続する
with psycopg.connect("dbname=test user=postgres") as conn:

    # データベースの操作を実行するカーソルをオープンする
    with conn.cursor() as cur:

        # コマンドの実行: 新しいテーブルを作成する
        cur.execute("""
            CREATE TABLE test (
                id serial PRIMARY KEY,
                num integer,
                data text)
            """)

        # クエリのプレースホルダーを埋めるためにデータを渡して
        # psycopg に正しい変換を行わせる (SQL インジェクションなし!)
        cur.execute(
            "INSERT INTO test (num, data) VALUES (%s, %s)",
            (100, "abc'def"))

        # データベースにクエリし、データを Python オブジェクトとして取得する
        cur.execute("SELECT * FROM test")
        cur.fetchone()
        # これは (1, 100, "abc'def") を返す

        # `cur.fetchmany()` や `cur.fetchall()` を使用して複数のレコードのリストを返したり
        # または、カーソルをイテレートすることもできる
        for record in cur:
            print(record)

        # データベースへの変更を永続化する
        conn.commit()

この例では、メインオブジェクトとメソッドの一部と、それらが互いにどう関係しているのかがわかります。

  • Connection クラスはデータベースセッションをカプセル化していて、これを使用して次のことができます。

    • cursor() メソッドを使用して、データベースコマンドとクエリを実行するための新しい Cursor インスタンスを作成できます。

    • commit()rollback() メソッドを使用してトランザクションを終端できます。

  • Cursor クラスを使用すると、次のようにデータベースとの対話ができます。

    • execute()executemany() などのメソッドを使用して、データベースにコマンドを送れます。

    • カーソル上でイテレートしたり、fetchone()fetchmany()fetchall() などのメソッドを使用したりして、データベースからデータを取得できます。

  • これらのオブジェクトをコンテクスト マネージャとして使用することで (つまり with を使用することで)、オブジェクトを確実にクローズしてオブジェクトのリソースをブロックの最後で開放できる (これは psycopg2 とは異なる ことに注意してください)。

参考

後に対処する必要になる重要なトピックがいくつかあります。

ショートカット#

上記のパターンは psycopg2 ユーザーには馴染みのあるものです。しかし、psycopg 3 は上記のパターンをより簡潔にするシンプルな拡張もいくつか公開しています。

  • Connection オブジェクトは、execute() メソッドを呼び出して返すカーソルの作成に相当する execute() メソッドを公開しています。

    # In Psycopg 2
    cur = conn.cursor()
    cur.execute(...)
    
    # In Psycopg 3
    cur = conn.execute(...)
    
  • Cursor.execute() メソッドは self を返します。つまり、fetchone() などの fetch 操作を execute() の呼び出しにチェーンできます。

    # In Psycopg 2
    cur.execute(...)
    record = cur.fetchone()
    
    cur.execute(...)
    for record in cur:
        ...
    
    # In Psycopg 3
    record = cur.execute(...).fetchone()
    
    for record in cur.execute(...):
        ...
    

単純なケースでは、これらを一緒に使うことで、コネクションの作成から1つの式の結果の使用までが実行できます。

print(psycopg.connect(DSN).execute("SELECT now()").fetchone()[0])
# 2042-07-12 18:15:10.706497+01:00

コネクション コンテクスト#

psycopg 3 の Connection はコンテクスト マネージャとして使用できます。

with psycopg.connect() as conn:
    ... # コネクションを使用する

# ここでコネクションは閉じられている

ブロックを出るときに、トランザクションがオープンであれば、そのトランザクションはコミットされます。ブロック内で例外が発生した場合、トランザクションはロールバックされます。どちらの場合もコネクションはクローズされます。これはおおよそ次のコードと同等です。

conn = psycopg.connect()
try:
    ... # コネクションを使用する
except BaseException:
    conn.rollback()
else:
    conn.commit()
finally:
    conn.close()

注釈

この動作は psycopg2 の動作とは異なります。psycopg2 では、最後の close() は存在せず、コネクションは異なるトランザクションを管理するために複数の with ステートメントで使用できます。この動作は非標準でユーザーを驚かせるものだと考えられてきたため、より明示的な transaction() ブロックと置換されました。

上記のパターンはほとんどの人が使うものですが、connect() がブロック自体に入るわけではなく、入る前のコネクション ("un-entered" connection) を返すことに注意してください。そのため、コネクションはコードのスコープに関わらずまだ使える可能性があり、開発者は必要なときに必要に応じて commit()rollback()close() を自由に使えます (そして、開発者にはそれらを呼び出す責任があります)。

警告

コネクションがそのままスコープ外に残された場合、with ブロックを使用する場合と使用しない場合でその動作方法は異なります。

  • コネクションが with ブロックなしで使用された場合、サーバーは INTRANS で閉じられたコネクションを探して現在のトランザクションをロールバックします。

  • コネクションが with ブロックとともに使用された場合、明示的な COMMIT があり、操作はファイナライズされます。

もし一連の操作をただ実行して、そして結果をコミットすることを意図しているのなら、with ブロックを使うべきです。これはコネクションを使用して行う最も一般的な操作です。コネクションのライフサイクルとトランザクションのパターンが異なり、コネクションをよりコントロールしたい場合には、with なしに使用するほうがより便利なことがあるかもしれません。

より詳しい情報については トランザクションの管理 を参照してください。

AsyncConnectionasync with を使用してコンテクスト マネージャとして使用できますが、変わった振る舞いをするため注意してください。詳細は with async コネクション を参照してください。

psycopg をプログラムに適応させる#

上記の 使用パターン はアダプターのデフォルトの動作を示したに過ぎません。psycopg は複数の方法でカスタマイズして、Python プログラムと PostgreSQL データベース間で最もスムーズなインテグレーションができるようになります。

  • カーソルが返すオブジェクトをタプルを受け取るのではなくカスタマイズしたい場合、行ファクトリ を指定できます。