モジュールの基本的な使用方法#
psycopg の基本的な使用方法は、DB-API プロトコルを実装しているすべてのデータべース アダプターと共通するものです。sqlite3
や psycopg2
などの他のデータベース アダプターには、おおよそ同じ対話のパターンがあります。
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()
この例では、メインオブジェクトとメソッドの一部と、それらが互いにどう関係しているのかがわかります。
関数
connect()
は、新しいデータベース セッションを作成し、新しいConnection
インスタンスを返します。AsyncConnection.connect()
は、代わりにasyncio
コネクションを返します。
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
なしに使用するほうがより便利なことがあるかもしれません。
より詳しい情報については トランザクションの管理 を参照してください。
AsyncConnection
も async with
を使用してコンテクスト マネージャとして使用できますが、変わった振る舞いをするため注意してください。詳細は with async コネクション を参照してください。
psycopg をプログラムに適応させる#
上記の 使用パターン はアダプターのデフォルトの動作を示したに過ぎません。psycopg は複数の方法でカスタマイズして、Python プログラムと PostgreSQL データベース間で最もスムーズなインテグレーションができるようになります。
プログラムが並行で スレッド/プロセスの代わりに
asyncio
を元にしている場合、async のコネクションとカーソル が利用できます。
カーソルが返すオブジェクトをタプルを受け取るのではなくカスタマイズしたい場合、行ファクトリ を指定できます。
Python の値と PostgreSQL の型を相互にマッピングする方法をカスタマイズしたい場合、基本的な型のマッピング に加えて、独自の型を設定 できます。