Cockroach数据库
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
安全套接字层配置
在运行Cockroach群集时,强烈建议使用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 docs 。
蟑螂扩展接口
这个 playhouse.cockroachdb
扩展模块提供以下类和助手:
CockroachDatabase
-的一个子类PostgresqlDatabase
,专门为与CRDB一起工作而设计。PooledCockroachDatabase
-与上面一样,但是实现了连接池。run_transaction()
-在事务内运行函数并提供自动客户端重试逻辑。
使用CRDB时可能有用的特殊字段类型:
UUIDKeyField
-使用CRDB的主键字段实现UUID
使用默认随机生成的UUID键入。RowIDField
-使用CRDB的主键字段实现INT
使用默认值键入unique_rowid()
.JSONField
-和博士后一样BinaryJSONField
,因为CRDB将JSON视为JSONB。ArrayField
-与Postgres扩展相同(但不支持多维数组)。
CRDB与Postgres的wire协议兼容,并且公开了一个非常相似的SQL接口,因此它是可能的(尽管 未推荐的 )使用 PostgresqlDatabase
使用CRDB:
CRDB不支持嵌套事务(保存点),因此
atomic()
方法已实现,以便在使用CockroachDatabase
. 了解更多信息 CRDB事务 .CRDB可能在字段类型、日期函数和Postgres的自省方面有细微差别。
CRDB的特定功能由
CockroachDatabase
,例如指定事务优先级或AS OF SYSTEM TIME
条款。
CRDB事务
CRDB不支持嵌套事务(保存点),因此 atomic()
方法在 CockroachDatabase
已修改为在遇到无效嵌套时引发异常。如果希望能够嵌套事务性代码,可以使用 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()
帮手。这个helper方法接受callable,它负责执行任何可能需要重试的事务语句。
最简单的例子 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应用程序接口
- class CockroachDatabase(database[, **kwargs])
CockroachDB数据库实现,基于
PostgresqlDatabase
并使用psycopg2
驱动程序。其他关键字参数被传递给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) -- “低”、“正常”或“高”。
- 返回:
返回回调返回的值。
- 加薪:
ExceededMaxAttempts
如果max_attempts
超过了。
在事务中运行SQL,并在客户端自动重试。
用户提供
callback
:Must 接受一个参数
db
实例,该实例表示正在运行事务的连接。Must 不尝试提交、回滚或以其他方式管理事务。
May 不止一次地被召唤。
应该 理想情况下只包含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')
- class PooledCockroachDatabase(database[, **kwargs])
CockroachDB连接池实现,基于
PooledPostgresqlDatabase
. 实现与相同的APICockroachDatabase
,但将执行客户端连接池。
- run_transaction(db, callback[, max_attempts=None[, system_time=None[, priority=None]]])
在事务中运行SQL,并在客户端自动重试。看到了吗
CockroachDatabase.run_transaction()
有关详细信息。- 参数:
db (CockroachDatabase) -- 数据库实例。
callback -- 可赎回的,接受单一
db
参数(与上面传递的值相同)。
备注
此函数等效于
CockroachDatabase
班级。
- class UUIDKeyField
使用CRDB的UUID主键字段
gen_random_uuid()
函数自动填充初始值。
- class RowIDField
使用CRDB的自动递增整数主键字段
unique_rowid()
函数自动填充初始值。
参见:
BinaryJSONField
从Postgresql扩展(在cockroachdb
扩展模块,并别名为JSONField
)ArrayField
从Postgresql扩展。