Cockroach Database
CockroachDB (CRDB) は peewee で十分にサポートされています。
from playhouse.cockroachdb import CockroachDatabase
db = CockroachDatabase('my_app', user='root', host='10.1.0.8')
Cockroach Cloud を使用している場合は、接続文字列を使用して接続パラメータを指定する方が簡単な場合があります。
db = CockroachDatabase('postgresql://root:secret@host:26257/defaultdb...')
注記
CockroachDB には、psycopg2
(postgres) Python ドライバが必要です。
注記
CockroachDB のインストールと入門ガイドはこちらにあります: https://www.cockroachlabs.com/docs/stable/install-cockroachdb.html
SSL 設定
Cockroach クラスタを実行する場合は、SSL 証明書を強くお勧めします。Psycopg2 は SSL をそのままサポートしていますが、データベースを初期化するときに追加のオプションを指定する必要がある場合があります。
db = CockroachDatabase(
'my_app',
user='root',
host='10.1.0.8',
sslmode='verify-full', # Verify the cert common-name.
sslrootcert='/path/to/root.crt')
# Or, alternatively, specified as part of a connection-string:
db = CockroachDatabase('postgresql://root:secret@host:26257/dbname'
'?sslmode=verify-full&sslrootcert=/path/to/root.crt'
'&options=--cluster=my-cluster-xyz')
クライアント検証の詳細については、libpq ドキュメント を参照してください。
Cockroach 拡張 API
playhouse.cockroachdb
拡張モジュールは、次のクラスとヘルパーを提供します。
CockroachDatabase
-PostgresqlDatabase
のサブクラスで、CRDB での作業用に特別に設計されています。PooledCockroachDatabase
- 上記と同様ですが、コネクションプーリングを実装しています。run_transaction()
- トランザクション内で関数を 실행하고、クライアント側の自動再試行ロジックを提供します。
CRDB を使用する際に役立つ特殊なフィールドタイプ
UUIDKeyField
- デフォルトでランダムに生成された UUID を使用して、CRDB のUUID
タイプを使用するプライマリキーフィールドの実装です。RowIDField
- デフォルトでunique_rowid()
を使用して、CRDB のINT
タイプを使用するプライマリキーフィールドの実装です。JSONField
- CRDB が JSON を JSONB として扱うため、Postgres のBinaryJSONField
と同じです。ArrayField
- Postgres 拡張と同じですが、多次元配列はサポートしていません。
CRDB は Postgres のワイヤプロトコルと互換性があり、非常に似た SQL インターフェースを公開しているため、PostgresqlDatabase
を CRDB で使用することは可能ですが、**お勧めしません**。
CRDB は入れ子になったトランザクション (セーブポイント) をサポートしていないため、
atomic()
メソッドは、CockroachDatabase
を使用している場合にこれを強制するために実装されました。詳細については、CRDB トランザクション を参照してください。CRDB は、フィールドタイプ、日付関数、イントロスペクションにおいて、Postgres と微妙な違いがある場合があります。
CRDB 固有の機能は、
CockroachDatabase
によって公開されます。たとえば、トランザクションの優先順位を指定したり、AS OF SYSTEM TIME
句を指定したりすることができます。
CRDB トランザクション
CRDB は入れ子になったトランザクション (セーブポイント) をサポートしていないため、CockroachDatabase
の atomic()
メソッドは、無効な入れ子が発生した場合に例外を発生させるように変更されました。トランザクションコードを入れ子にできるようにするには、transaction()
メソッドを使用します。このメソッドは、最も外側のブロックがトランザクションを管理するようにします (たとえば、入れ子になったブロックを終了しても早期コミットは発生しません)。
例
@db.transaction()
def create_user(username):
return User.create(username=username)
def some_other_function():
with db.transaction() as txn:
# do some stuff...
# This function is wrapped in a transaction, but the nested
# transaction will be ignored and folded into the outer
# transaction, as we are already in a wrapped-block (via the
# context manager).
create_user('some_user@example.com')
# do other stuff.
# At this point we have exited the outer-most block and the transaction
# will be committed.
return
CRDB は、特別な run_transaction()
ヘルパーを使用して利用できる、クライアント側のトランザクション再試行を提供します。このヘルパーメソッドは、再試行が必要になる可能性のあるトランザクションステートメントを実行する役割を持つ呼び出し可能オブジェクトを受け入れます。
run_transaction()
の最も簡単な例
def create_user(email):
# Callable that accepts a single argument (the database instance) and
# which is responsible for executing the transactional SQL.
def callback(db_ref):
return User.create(email=email)
return db.run_transaction(callback, max_attempts=10)
huey = create_user('huey@example.com')
注記
指定された回数試行してもトランザクションをコミットできない場合は、cockroachdb.ExceededMaxAttempts
例外が発生します。SQL の形式が正しくない場合、制約に違反している場合などは、関数は呼び出し元に例外を発生させます。
あるアカウントから別のアカウントに金額を転送するトランザクションのクライアント側再試行を実装するために run_transaction()
を使用した例
from playhouse.cockroachdb import CockroachDatabase
db = CockroachDatabase('my_app')
def transfer_funds(from_id, to_id, amt):
"""
Returns a 3-tuple of (success?, from balance, to balance). If there are
not sufficient funds, then the original balances are returned.
"""
def thunk(db_ref):
src, dest = (Account
.select()
.where(Account.id.in_([from_id, to_id])))
if src.id != from_id:
src, dest = dest, src # Swap order.
# Cannot perform transfer, insufficient funds!
if src.balance < amt:
return False, src.balance, dest.balance
# Update each account, returning the new balance.
src, = (Account
.update(balance=Account.balance - amt)
.where(Account.id == from_id)
.returning(Account.balance)
.execute())
dest, = (Account
.update(balance=Account.balance + amt)
.where(Account.id == to_id)
.returning(Account.balance)
.execute())
return True, src.balance, dest.balance
# Perform the queries that comprise a logical transaction. In the
# event the transaction fails due to contention, it will be auto-
# matically retried (up to 10 times).
return db.run_transaction(thunk, max_attempts=10)
CRDB API
- class CockroachDatabase(database[, **kwargs])
PostgresqlDatabase
に基づき、psycopg2
ドライバを使用する CockroachDB 実装です。追加のキーワード引数は psycopg2 接続コンストラクタに渡され、データベースの
user
、port
などを指定するために使用できます。あるいは、接続の詳細は URL 形式で指定できます。
- run_transaction(callback[, max_attempts=None[, system_time=None[, priority=None]]])
- パラメータ
**callback** - 単一の
db
パラメータ (このメソッドが呼び出されるデータベースインスタンスになります) を受け入れる呼び出し可能オブジェクトです。**max_attempts** (int) - あきらめる前に試行する最大回数です。
**system_time** (datetime) - 指定された値に関して、
AS OF SYSTEM TIME
としてトランザクションを実行します。**priority** (str) - 「low」、「normal」、または「high」のいずれかです。
- 戻り値
コールバックによって返された値を返します。
- 例外
max_attempts
を超えた場合は、ExceededMaxAttempts
が発生します。
クライアント側の自動再試行を使用して、トランザクションで SQL を実行します。
ユーザー提供の
callback
**必須** 1 つのパラメータ、トランザクションが実行されている接続を表す
db
インスタンスを受け入れる必要があります。**必須** コミット、ロールバック、またはその他の方法でトランザクションを管理しようとしないでください。
**可能性あり** 複数回呼び出される場合があります。
**推奨** 理想的には SQL 操作のみを含める必要があります。
さらに、CRDB は入れ子になったトランザクションをサポートしていないため、この関数が呼び出されるときにデータベースに開いているトランザクションがあってはなりません。そうしようとすると、
NotImplementedError
が発生します。最も簡単な例
def create_user(email): def callback(db_ref): return User.create(email=email) return db.run_transaction(callback, max_attempts=10) user = create_user('huey@example.com')
- クラス PooledCockroachDatabase(database[, **kwargs])
PooledPostgresqlDatabase
に基づいた、CockroachDBのコネクションプーリング実装です。CockroachDatabase
と同じAPIを実装していますが、クライアント側でコネクションプーリングを行います。
- run_transaction(db, callback[, max_attempts=None[, system_time=None[, priority=None]]])
クライアント側で自動リトライを行うトランザクション内でSQLを実行します。詳細は
CockroachDatabase.run_transaction()
を参照してください。- パラメータ
db (CockroachDatabase) – データベースインスタンス。
callback – 単一の`db`パラメータ(上記で渡された値と同じ)を受け入れる呼び出し可能なオブジェクト。
注記
この関数は、
CockroachDatabase
クラスの同名のメソッドと同等です。
- クラス UUIDKeyField
CRDBの`gen_random_uuid()`関数を使用して初期値を自動的に設定する、UUID主キーフィールドです。
- クラス RowIDField
CRDBの`unique_rowid()`関数を使用して初期値を自動的に設定する、自動インクリメント整数主キーフィールドです。
関連項目
Postgresql拡張の
BinaryJSONField
(`cockroachdb`拡張モジュールで利用可能、`JSONField`のエイリアス)。Postgresql拡張の
ArrayField
。