API 文档
本文档指定了 Peewee 的 API。
数据库
- class Database(database[, thread_safe=True[, field_types=None[, operations=None[, autoconnect=True[, **kwargs]]]]])
- 参数
database (str) – 数据库名称或 SQLite 的文件名(或
None
以 延迟初始化,在这种情况下,您必须调用Database.init()
,指定数据库名称)。thread_safe (bool) – 是否在线程本地存储连接状态。
field_types (dict) – 支持的附加字段类型的映射。
operations (dict) – 支持的附加操作的映射。
autoconnect (bool) – 如果尝试在关闭的数据库上执行查询,则自动连接到数据库。
kwargs – 当创建连接时传递给数据库驱动程序的任意关键字参数,例如
password
、host
等。
Database
负责执行查询
管理连接
事务
内省
注意
如果数据库在运行时之前未知,则可以使用
None
作为数据库名称实例化数据库。这样,您可以创建数据库实例,然后在设置已知时在其他地方配置它。这称为 延迟初始化。示例
# Sqlite database using WAL-mode and 32MB page-cache. db = SqliteDatabase('app.db', pragmas={ 'journal_mode': 'wal', 'cache_size': -32 * 1000}) # Postgresql database on remote host. db = PostgresqlDatabase('my_app', user='postgres', host='10.1.0.3', password='secret')
延迟初始化示例
db = PostgresqlDatabase(None) class BaseModel(Model): class Meta: database = db # Read database connection info from env, for example: db_name = os.environ['DATABASE'] db_host = os.environ['PGHOST'] # Initialize database. db.init(db_name, host=db_host, user='postgres')
- param = '?'
用作 SQL 查询中参数占位符的字符串。
- quote = '"'
用于表示表或列等实体的引号类型。
- init(database[, **kwargs])
- 参数
database (str) – 数据库名称或 SQLite 的文件名。
kwargs – 当创建连接时传递给数据库驱动程序的任意关键字参数,例如
password
、host
等。
初始化一个延迟数据库。有关更多信息,请参阅 运行时数据库配置。
- connection_context()
创建一个上下文管理器,它将在包装块的持续时间内保持连接打开状态。
示例
def on_app_startup(): # When app starts up, create the database tables, being sure # the connection is closed upon completion. with database.connection_context(): database.create_tables(APP_MODELS)
- connect([reuse_if_open=False])
- 参数
reuse_if_open (bool) – 如果连接已打开,则不引发异常。
- 返回值
是否打开了一个新连接。
- 返回类型
bool
- 引发
OperationalError
如果连接已打开且reuse_if_open
未设置为True
。
打开与数据库的连接。
- close()
- 返回值
是否关闭了连接。如果数据库已关闭,则返回
False
。- 返回类型
bool
关闭与数据库的连接。
- is_closed()
- 返回值
如果数据库已关闭,则返回
True
,如果已打开,则返回False
。- 返回类型
bool
- connection()
返回打开的连接。如果连接未打开,则将打开一个连接。连接将是底层数据库驱动程序用于封装数据库连接的任何内容。
- cursor([named_cursor=None])
- 参数
named_cursor – 用于内部使用。
返回当前连接上的
cursor
对象。如果连接未打开,则将打开一个连接。游标将是底层数据库驱动程序用于封装数据库游标的任何内容。
- execute_sql(sql[, params=None])
- 参数
sql (str) – 要执行的 SQL 字符串。
params (tuple) – 查询参数。
- 返回值
游标对象。
执行 SQL 查询并返回结果上的游标。
- execute(query[, **context_options])
- 参数
query – 一个
Query
实例。context_options – 传递给 SQL 生成器的任意选项。
- 返回值
游标对象。
通过编译一个
Query
实例并执行生成的 SQL 来执行 SQL 查询。
- last_insert_id(cursor[, query_type=None])
- 参数
cursor – 游标对象。
- 返回值
最后插入行的主键。
- rows_affected(cursor)
- 参数
cursor – 游标对象。
- 返回值
查询修改的行数。
- in_transaction()
- 返回值
当前是否打开事务。
- 返回类型
bool
- atomic([...])
创建一个上下文管理器,它将在包装块中以事务(或如果块嵌套,则以保存点)运行任何查询。
对
atomic()
的调用可以嵌套。atomic()
也可以用作装饰器。特定于数据库的参数
PostgresqlDatabase
和MySQLDatabase
接受一个isolation_level
参数。SqliteDatabase
接受一个lock_type
参数。- 参数
isolation_level (str) – 隔离策略:SERIALIZABLE、READ COMMITTED、REPEATABLE READ、READ UNCOMMITTED
lock_type (str) – 锁定策略:DEFERRED、IMMEDIATE、EXCLUSIVE。
示例代码
with db.atomic() as txn: perform_operation() with db.atomic() as nested_txn: perform_another_operation()
可以在包装块内显式提交或回滚事务和保存点。如果发生这种情况,则在提交/回滚后开始新的事务或保存点。
示例
with db.atomic() as txn: User.create(username='mickey') txn.commit() # Changes are saved and a new transaction begins. User.create(username='huey') txn.rollback() # "huey" will not be saved. User.create(username='zaizee') # Print the usernames of all users. print([u.username for u in User.select()]) # Prints ["mickey", "zaizee"]
- manual_commit()
创建一个上下文管理器,它在包装块的持续时间内禁用所有事务管理。
示例
with db.manual_commit(): db.begin() # Begin transaction explicitly. try: user.delete_instance(recursive=True) except: db.rollback() # Rollback -- an error occurred. raise else: try: db.commit() # Attempt to commit changes. except: db.rollback() # Error committing, rollback. raise
上面的代码等效于以下代码
with db.atomic(): user.delete_instance(recursive=True)
- session_start()
开始一个新的事务(不使用上下文管理器或装饰器)。如果您打算在事务中执行一系列操作,但使用装饰器或上下文管理器不合适,则此方法很有用。
注意
强烈建议您尽可能使用
Database.atomic()
方法来管理事务/保存点。atomic
方法正确管理嵌套,使用适当的构造(例如,事务与保存点),并始终清理自身。仅当操作序列不容易使用上下文管理器或装饰器包装时,才应使用
session_start()
方法。警告
在调用
session_start
方法后,您必须始终调用session_commit()
或session_rollback()
。
- session_commit()
提交使用
session_start()
开始的事务期间所做的任何更改。
- session_rollback()
回滚使用
session_start()
开始的事务期间所做的任何更改。
- transaction([...])
创建一个上下文管理器,该管理器在事务中运行包装块中的所有查询。
特定于数据库的参数
PostgresqlDatabase
和MySQLDatabase
接受一个isolation_level
参数。SqliteDatabase
接受一个lock_type
参数。- 参数
isolation_level (str) – 隔离策略:SERIALIZABLE、READ COMMITTED、REPEATABLE READ、READ UNCOMMITTED
lock_type (str) – 锁定策略:DEFERRED、IMMEDIATE、EXCLUSIVE。
警告
对
transaction
的调用不能嵌套。只有最顶层的调用才会生效。回滚或提交嵌套的事务上下文管理器具有未定义的行为。
- savepoint()
创建一个上下文管理器,该管理器在保存点中运行包装块中的所有查询。保存点可以任意嵌套。
警告
对
savepoint
的调用必须发生在事务中。
- begin()
在使用手动提交模式时开始事务。
注意
此方法应仅与
manual_commit()
上下文管理器结合使用。
- commit()
手动提交当前活动的事务。
注意
此方法应仅与
manual_commit()
上下文管理器结合使用。
- rollback()
手动回滚当前活动的事务。
注意
此方法应仅与
manual_commit()
上下文管理器结合使用。
- batch_commit(it, n)
- 参数
it (iterable) – 将被生成的项目的迭代器。
n (int) – 每n个项目提交一次。
- 返回值
与提供的迭代器等效的迭代器,此外,n 个项目的组将在事务中生成。
此方法的目的是简化大型操作(如插入、更新等)的批处理。您传入一个迭代器和每个批次的项目数量,这些项目将由一个等效的迭代器返回,该迭代器将每个批次包装在一个事务中。
示例
# Some list or iterable containing data to insert. row_data = [{'username': 'u1'}, {'username': 'u2'}, ...] # Insert all data, committing every 100 rows. If, for example, # there are 789 items in the list, then there will be a total of # 8 transactions (7x100 and 1x89). for row in db.batch_commit(row_data, 100): User.create(**row)
另一种可能更有效的方法是将数据批处理到一个多值
INSERT
语句中(例如,使用Model.insert_many()
)。with db.atomic(): for idx in range(0, len(row_data), 100): # Insert 100 rows at a time. rows = row_data[idx:idx + 100] User.insert_many(rows).execute()
- table_exists(table[, schema=None])
- 参数
table (str) – 表名。
schema (str) – 模式名称(可选)。
- 返回值
bool
指示表是否存在。
- get_tables([schema=None])
- 参数
schema (str) – 模式名称(可选)。
- 返回值
数据库中表名的列表。
- get_indexes(table[, schema=None])
- 参数
table (str) – 表名。
schema (str) – 模式名称(可选)。
返回
IndexMetadata
元组的列表。示例
print(db.get_indexes('entry')) [IndexMetadata( name='entry_public_list', sql='CREATE INDEX "entry_public_list" ...', columns=['timestamp'], unique=False, table='entry'), IndexMetadata( name='entry_slug', sql='CREATE UNIQUE INDEX "entry_slug" ON "entry" ("slug")', columns=['slug'], unique=True, table='entry')]
- get_columns(table[, schema=None])
- 参数
table (str) – 表名。
schema (str) – 模式名称(可选)。
返回
ColumnMetadata
元组的列表。示例
print(db.get_columns('entry')) [ColumnMetadata( name='id', data_type='INTEGER', null=False, primary_key=True, table='entry'), ColumnMetadata( name='title', data_type='TEXT', null=False, primary_key=False, table='entry'), ...]
- get_primary_keys(table[, schema=None])
- 参数
table (str) – 表名。
schema (str) – 模式名称(可选)。
返回构成主键的列名列表。
示例
print(db.get_primary_keys('entry')) ['id']
- get_foreign_keys(table[, schema=None])
- 参数
table (str) – 表名。
schema (str) – 模式名称(可选)。
返回表上存在的键的
ForeignKeyMetadata
元组列表。示例
print(db.get_foreign_keys('entrytag')) [ForeignKeyMetadata( column='entry_id', dest_table='entry', dest_column='id', table='entrytag'), ...]
- get_views([schema=None])
- 参数
schema (str) – 模式名称(可选)。
返回数据库中存在的 VIEW 的
ViewMetadata
元组列表。示例
print(db.get_views()) [ViewMetadata( name='entries_public', sql='CREATE VIEW entries_public AS SELECT ... '), ...]
- sequence_exists(seq)
- 参数
seq (str) – 序列的名称。
- 返回值
序列是否存在。
- 返回类型
bool
- create_tables(models[, **options])
- 参数
models (list) –
Model
类的列表。options – 在调用
Model.create_table()
时指定的选项。
为给定的模型列表创建表、索引和相关元数据。
解析依赖项,以便按适当的顺序创建表。
- drop_tables(models[, **options])
- 参数
models (list) –
Model
类的列表。kwargs – 在调用
Model.drop_table()
时指定的选项。
删除给定的模型列表的表、索引和相关元数据。
解析依赖项,以便按适当的顺序删除表。
- bind(models[, bind_refs=True[, bind_backrefs=True]])
- 参数
models (list) – 要绑定的一个或多个
Model
类。bind_refs (bool) – 绑定相关模型。
bind_backrefs (bool) – 绑定反向引用相关模型。
将给定的模型列表和指定的关联绑定到数据库。
- bind_ctx(models[, bind_refs=True[, bind_backrefs=True]])
- 参数
models (list) – 要绑定到数据库的模型列表。
bind_refs (bool) – 绑定使用外键引用的模型。
bind_backrefs (bool) – 绑定使用外键引用给定模型的模型。
创建一个上下文管理器,该管理器在包装块的持续时间内将给定的模型绑定(关联)到当前数据库。
示例
MODELS = (User, Account, Note) # Bind the given models to the db for the duration of wrapped block. def use_test_database(fn): @wraps(fn) def inner(self): with test_db.bind_ctx(MODELS): test_db.create_tables(MODELS) try: fn(self) finally: test_db.drop_tables(MODELS) return inner class TestSomething(TestCase): @use_test_database def test_something(self): # ... models are bound to test database ... pass
- extract_date(date_part, date_field)
- 参数
date_part (str) – 要提取的日期部分,例如“year”。
date_field (Node) – 包含日期/时间的 SQL 节点,例如
DateTimeField
.
- 返回值
表示函数调用的 SQL 节点,该函数调用将返回提供的日期部分。
提供用于提取日期时间部分的兼容接口。
- truncate_date(date_part, date_field)
- 参数
date_part (str) – 要截断到的日期部分,例如“day”。
date_field (Node) – 包含日期/时间的 SQL 节点,例如
DateTimeField
.
- 返回值
表示函数调用的 SQL 节点,该函数调用将返回截断的日期部分。
提供用于将日期时间截断到给定分辨率的兼容接口。
- random()
- 返回值
表示函数调用的 SQL 节点,该函数调用返回随机值。
调用数据库提供的适当随机数生成函数的兼容接口。对于 Postgres 和 Sqlite,这等效于
fn.random()
,对于 MySQLfn.rand()
。
- class SqliteDatabase(database[, pragmas=None[, timeout=5[, returning_clause=None[, **kwargs]]]])
- 参数
pragmas – 字典或包含要设置的 pragma 键和值的 2 元组列表,每次打开连接时都会设置。
timeout – 设置 SQLite 驱动程序的繁忙超时(以秒为单位)。
returning_clause (bool) – 对于批量 INSERT 查询自动使用 RETURNING 子句(需要 Sqlite 3.35 或更高版本)。
Sqlite 数据库实现。
SqliteDatabase
提供了 Sqlite 独有的某些高级功能。注册自定义聚合、排序规则和函数
加载 C 扩展
高级事务(指定锁定类型)
有关更多功能,请参阅
SqliteExtDatabase
.
初始化数据库并配置一些 PRAGMA 的示例
db = SqliteDatabase('my_app.db', pragmas=( ('cache_size', -16000), # 16MB ('journal_mode', 'wal'), # Use write-ahead-log journal mode. )) # Alternatively, pragmas can be specified using a dictionary. db = SqliteDatabase('my_app.db', pragmas={'journal_mode': 'wal'})
- pragma(key[, value=SENTINEL[, permanent=False]])
- 参数
key – 设置名称。
value – 设置的新值(可选)。
permanent – 每次打开连接时应用此 pragma。
在活动连接上执行 PRAGMA 查询一次。如果未指定值,则将返回当前值。
如果指定了
permanent
,则 PRAGMA 查询还将在每次打开新连接时执行,确保它始终有效。注意
默认情况下,这仅影响当前连接。如果正在执行的 PRAGMA 不是永久性的,则必须指定
permanent=True
以确保在后续连接上设置 pragma。
- cache_size
获取或设置当前连接的 cache_size pragma。
- foreign_keys
获取或设置当前连接的 foreign_keys pragma。
- journal_mode
获取或设置 journal_mode pragma。
- journal_size_limit
获取或设置 journal_size_limit pragma。
- mmap_size
获取或设置当前连接的 mmap_size pragma。
- page_size
获取或设置 page_size pragma。
- read_uncommitted
获取或设置当前连接的 read_uncommitted pragma。
- synchronous
获取或设置当前连接的 synchronous pragma。
- wal_autocheckpoint
获取或设置当前连接的 wal_autocheckpoint pragma。
- timeout
获取或设置繁忙超时(秒)。
- register_aggregate(klass[, name=None[, num_params=-1]])
- 参数
klass – 实现聚合 API 的类。
name (str) – 聚合函数名称(默认为类名)。
num_params (int) – 聚合接受的参数数量,或 -1 表示任何数量。
注册用户定义的聚合函数。
每次打开新连接时都会注册该函数。此外,如果连接已打开,则聚合将与打开的连接一起注册。
- aggregate([name=None[, num_params=-1]])
- 参数
name (str) – 聚合的名称(默认为类名)。
num_params (int) – 聚合接受的参数数量,或 -1 表示任何数量。
用于注册用户定义的聚合函数的类装饰器。
示例
@db.aggregate('md5') class MD5(object): def initialize(self): self.md5 = hashlib.md5() def step(self, value): self.md5.update(value) def finalize(self): return self.md5.hexdigest() @db.aggregate() class Product(object): '''Like SUM() except calculates cumulative product.''' def __init__(self): self.product = 1 def step(self, value): self.product *= value def finalize(self): return self.product
- register_collation(fn[, name=None])
- 参数
fn – 排序规则函数。
name (str) – 排序规则的名称(默认为函数名称)
注册用户定义的排序规则。每次打开新连接时都会注册排序规则。此外,如果连接已打开,则排序规则将与打开的连接一起注册。
- collation([name=None])
- 参数
name (str) – 排序规则的名称(默认为函数名称)
用于注册用户定义的排序规则的装饰器。
示例
@db.collation('reverse') def collate_reverse(s1, s2): return -cmp(s1, s2) # Usage: Book.select().order_by(collate_reverse.collation(Book.title)) # Equivalent: Book.select().order_by(Book.title.asc(collation='reverse'))
您可能已经注意到,原始的
collate_reverse
函数有一个名为collation
的特殊属性附加到它。此额外属性提供了一种简便方法来生成使用自定义排序规则所需的 SQL。
- register_function(fn[, name=None[, num_params=-1[, deterministic=None]]])
- 参数
fn – 用户定义的标量函数。
name (str) – 函数的名称(默认为函数名称)
num_params (int) – 函数接受的参数数量,或 -1 表示任何数量。
确定性 (bool) – 函数对于给定输入是否确定性(这需要在索引中使用该函数)。需要 Sqlite 3.20 或更高版本,以及
sqlite3
驱动程序支持(在 Python 3.8 中添加到标准库)。
注册用户定义的标量函数。每次打开新连接时都会注册该函数。此外,如果连接已打开,则该函数将与打开的连接一起注册。
- func([name=None[, num_params=-1[, deterministic=None]]])
- 参数
name (str) – 函数的名称(默认为函数名称)。
num_params (int) – 函数接受的参数数量,或 -1 表示任意数量。
确定性 (bool) – 函数对于给定输入是否确定性(这需要在索引中使用该函数)。需要 Sqlite 3.20 或更高版本,以及
sqlite3
驱动程序支持(在 Python 3.8 中添加到标准库)。
装饰器,用于注册用户定义的标量函数。
示例
@db.func('title_case') def title_case(s): return s.title() if s else '' # Usage: title_case_books = Book.select(fn.title_case(Book.title))
- register_window_function(klass[, name=None[, num_params=-1]])
- 参数
klass – 实现窗口函数 API 的类。
name (str) – 窗口函数名称(默认为类的名称)。
num_params (int) – 函数接受的参数数量,或 -1 表示任意数量。
注册用户定义的窗口函数。
注意
此功能需要 SQLite >= 3.25.0 **以及** pysqlite3 >= 0.2.0。
每次打开新连接时都会注册窗口函数。此外,如果连接已打开,则窗口函数将与打开的连接一起注册。
- window_function([name=None[, num_params=-1]])
- 参数
name (str) – 窗口函数的名称(默认为类名)。
num_params (int) – 函数接受的参数数量,或 -1 表示任意数量。
类装饰器,用于注册用户定义的窗口函数。窗口函数必须定义以下方法
step(<params>)
- 从一行接收值并更新状态。inverse(<params>)
-step()
的逆函数,用于给定值。value()
- 返回窗口函数的当前值。finalize()
- 返回窗口函数的最终值。
示例
@db.window_function('my_sum') class MySum(object): def __init__(self): self._value = 0 def step(self, value): self._value += value def inverse(self, value): self._value -= value def value(self): return self._value def finalize(self): return self._value
- table_function([name=None])
用于注册
TableFunction
的类装饰器。表函数是用户定义的函数,它们不是返回单个标量值,而是可以返回任意数量的表格数据的行。示例
from playhouse.sqlite_ext import TableFunction @db.table_function('series') class Series(TableFunction): columns = ['value'] params = ['start', 'stop', 'step'] def initialize(self, start=0, stop=None, step=1): """ Table-functions declare an initialize() method, which is called with whatever arguments the user has called the function with. """ self.start = self.current = start self.stop = stop or float('Inf') self.step = step def iterate(self, idx): """ Iterate is called repeatedly by the SQLite database engine until the required number of rows has been read **or** the function raises a `StopIteration` signalling no more rows are available. """ if self.current > self.stop: raise StopIteration ret, self.current = self.current, self.current + self.step return (ret,) # Usage: cursor = db.execute_sql('SELECT * FROM series(?, ?, ?)', (0, 5, 2)) for value, in cursor: print(value) # Prints: # 0 # 2 # 4
- unregister_aggregate(name)
- 参数
name – 用户定义的聚合函数的名称。
注销用户定义的聚合函数。
- unregister_collation(name)
- 参数
name – 用户定义的排序规则的名称。
注销用户定义的排序规则。
- unregister_function(name)
- 参数
name – 用户定义的标量函数的名称。
注销用户定义的标量函数。
- unregister_table_function(name)
- 参数
name – 用户定义的表函数的名称。
- 返回值
True 或 False,取决于该函数是否已删除。
注销用户定义的标量函数。
- load_extension(extension_module)
加载给定的 C 扩展。如果当前在调用线程中打开连接,则该扩展将为该连接以及所有后续连接加载。
例如,如果您已编译闭包表扩展并希望在您的应用程序中使用它,您可能会编写
db = SqliteExtDatabase('my_app.db') db.load_extension('closure')
- attach(filename, name)
- 参数
filename (str) – 要附加的数据库(或
:memory:
表示内存中)name (str) – 附加数据库的模式名称。
- 返回值
指示成功的布尔值
注册另一个数据库文件,该文件将附加到每个数据库连接。如果主数据库当前已连接,则新数据库将附加到打开的连接上。
注意
使用此方法附加的数据库将在每次打开数据库连接时附加。
- detach(name)
- 参数
name (str) – 附加数据库的模式名称。
- 返回值
指示成功的布尔值
注销先前使用
attach()
调用附加的另一个数据库文件。如果主数据库当前已连接,则附加的数据库将从打开的连接中分离。
- atomic([lock_type=None])
- 参数
lock_type (str) – 锁定策略:DEFERRED、IMMEDIATE、EXCLUSIVE。
创建一个原子上下文管理器,可以选择使用指定的锁定策略(如果未指定,则使用 DEFERRED)。
注意
锁定类型仅适用于最外层的
atomic()
块。
- transaction([lock_type=None])
- 参数
lock_type (str) – 锁定策略:DEFERRED、IMMEDIATE、EXCLUSIVE。
使用指定的锁定策略(默认为 DEFERRED)创建一个事务上下文管理器。
- class PostgresqlDatabase(database[, register_unicode=True[, encoding=None[, isolation_level=None]]])
Postgresql 数据库实现。
其他可选的关键字参数
- 参数
register_unicode (bool) – 注册 unicode 类型。
encoding (str) – 数据库编码。
isolation_level (int) – 隔离级别常量,在
psycopg2.extensions
模块中定义。
- set_time_zone(timezone)
- 参数
timezone (str) – 时区名称,例如“US/Central”。
- 返回值
没有返回值。
设置当前连接的时区。如果未打开连接,则将打开一个连接。
- atomic([isolation_level=None])
- 参数
isolation_level (str) – 隔离策略:SERIALIZABLE、READ COMMITTED、REPEATABLE READ、READ UNCOMMITTED
创建一个原子上下文管理器,可以选择使用指定的隔离级别(如果未指定,则使用服务器默认值)。
注意
隔离级别仅适用于最外层的
atomic()
块。
- transaction([isolation_level=None])
- 参数
isolation_level (str) – 隔离策略:SERIALIZABLE、READ COMMITTED、REPEATABLE READ、READ UNCOMMITTED
创建一个事务上下文管理器,可以选择使用指定的隔离级别(如果未指定,则使用服务器默认值)。
- class MySQLDatabase(database[, **kwargs])
MySQL 数据库实现。
- atomic([isolation_level=None])
- 参数
isolation_level (str) – 隔离策略:SERIALIZABLE、READ COMMITTED、REPEATABLE READ、READ UNCOMMITTED
创建一个原子上下文管理器,可以选择使用指定的隔离级别(如果未指定,则使用服务器默认值)。
注意
隔离级别仅适用于最外层的
atomic()
块。
- transaction([isolation_level=None])
- 参数
isolation_level (str) – 隔离策略:SERIALIZABLE、READ COMMITTED、REPEATABLE READ、READ UNCOMMITTED
创建一个事务上下文管理器,可以选择使用指定的隔离级别(如果未指定,则使用服务器默认值)。
查询构建器
- class Node
构成 SQL 查询 AST 的所有组件的基类。
- static copy(method)
用于 Node 方法的装饰器,这些方法会改变节点的状态。这允许方法链,例如
query = MyModel.select() new_query = query.where(MyModel.field == 'value')
- unwrap()
用于递归地展开“包装”节点的 API。基本情况是返回 self。
- is_alias()
用于确定节点在任何时候是否被用户显式别名化的 API。
- class Source([alias=None])
行元组的来源,例如表、联接或选择查询。默认情况下,提供一个名为“c”的“魔术”属性,它是一个用于列/属性查找的工厂,例如
User = Table('users') query = (User .select(User.c.username) .where(User.c.active == True) .order_by(User.c.username))
- alias(name)
返回应用了给定别名的对象的副本。
- select(*columns)
- 参数
columns –
Column
实例、表达式、函数、子查询或任何其他您想选择的内容。
在表上创建一个
Select
查询。如果表显式声明列并且没有提供列,则默认情况下将选择表的所有定义的列。
- join(dest[, join_type='INNER'[, on=None]])
-
联接类型可以是以下之一
JOIN.INNER
JOIN.LEFT_OUTER
JOIN.RIGHT_OUTER
JOIN.FULL
JOIN.FULL_OUTER
JOIN.CROSS
- class BaseTable
表类对象的基类,支持通过运算符重载进行联接。
- __and__(dest)
对
dest
执行 INNER 联接。
- __add__(dest)
对
dest
执行 LEFT OUTER 联接。
- __sub__(dest)
对
dest
执行 RIGHT OUTER 联接。
- __or__(dest)
对
dest
执行 FULL OUTER 联接。
- __mul__(dest)
对
dest
执行 CROSS 联接。
- class Table(name[, columns=None[, primary_key=None[, schema=None[, alias=None]]]])
表示数据库中的表(或类似表的对象,例如视图)。
- 参数
name (str) – 数据库表名
columns (tuple) – 列名列表(可选)。
primary_key (str) – 主键列的名称。
schema (str) – 用于访问表的模式名称(如果需要)。
alias (str) – 在 SQL 查询中使用的表的别名。
注意
如果指定了列,则将禁用“c”魔术属性。
当未显式定义列时,表具有一个特殊的属性“c”,它是一个工厂,可以动态地访问表列。
示例
User = Table('users') query = (User .select(User.c.id, User.c.username) .order_by(User.c.username))
当指定列时的等效示例
User = Table('users', ('id', 'username')) query = (User .select(User.id, User.username) .order_by(User.username))
- bind([database=None])
- 参数
database –
Database
对象。
将此表绑定到给定的数据库(或通过留空来取消绑定)。
当表绑定到数据库时,可以对它执行查询,而无需在查询的执行方法中指定数据库。
- select(*columns)
- 参数
columns –
Column
实例、表达式、函数、子查询或任何其他您想选择的内容。
在表上创建一个
Select
查询。如果表显式声明列并且没有提供列,则默认情况下将选择表的所有定义的列。示例
User = Table('users', ('id', 'username')) # Because columns were defined on the Table, we will default to # selecting both of the User table's columns. # Evaluates to SELECT id, username FROM users query = User.select() Note = Table('notes') query = (Note .select(Note.c.content, Note.c.timestamp, User.username) .join(User, on=(Note.c.user_id == User.id)) .where(Note.c.is_published == True) .order_by(Note.c.timestamp.desc())) # Using a function to select users and the number of notes they # have authored. query = (User .select( User.username, fn.COUNT(Note.c.id).alias('n_notes')) .join( Note, JOIN.LEFT_OUTER, on=(User.id == Note.c.user_id)) .order_by(fn.COUNT(Note.c.id).desc()))
- insert([insert=None[, columns=None[, **kwargs]]])
- 参数
insert – 将列映射到值的字典,生成字典的可迭代对象(即列表),或
Select
查询。columns (list) – 当插入的数据不是字典时,要插入的列列表。
kwargs – 列名到值的映射。
创建一个
Insert
查询到表中。
- class Join(lhs, rhs[, join_type=JOIN.INNER[, on=None[, alias=None]]])
表示两个表状对象之间的 JOIN。
- 参数
lhs – 连接的左侧。
rhs – 连接的右侧。
join_type – 连接类型。例如 JOIN.INNER、JOIN.LEFT_OUTER 等。
on – 描述连接谓词的表达式。
alias (str) – 应用于连接数据的别名。
- on(predicate)
- 参数
predicate (Expression) – 连接谓词。
指定用于此连接的谓词表达式。
- class ValuesList(values[, columns=None[, alias=None]])
表示可以像表一样使用的值列表。
- 参数
values – 包含要表示的行数据的列表列表。
columns (list) – 要赋予每行中列的名称。
alias (str) – 用于值列表的别名。
示例
data = [(1, 'first'), (2, 'second')] vl = ValuesList(data, columns=('idx', 'name')) query = (vl .select(vl.c.idx, vl.c.name) .order_by(vl.c.idx)) # Yields: # SELECT t1.idx, t1.name # FROM (VALUES (1, 'first'), (2, 'second')) AS t1(idx, name) # ORDER BY t1.idx
- columns(*names)
- 参数
names – 要应用于数据列的名称。
示例
vl = ValuesList([(1, 'first'), (2, 'second')]) vl = vl.columns('idx', 'name').alias('v') query = vl.select(vl.c.idx, vl.c.name) # Yields: # SELECT v.idx, v.name # FROM (VALUES (1, 'first'), (2, 'second')) AS v(idx, name)
- class CTE(name, query[, recursive=False[, columns=None]])
表示一个公用表表达式。例如查询,请参见 公用表表达式。
- 参数
name – CTE 的名称。
query –
Select
描述 CTE 的查询。recursive (bool) – CTE 是否是递归的。
columns (list) – CTE 生成的显式列列表(可选)。
- class ColumnBase
类似列对象的基类,属性或表达式。
类似列的对象可以使用各种运算符和特殊方法进行组合。
&
: 逻辑 AND|
: 逻辑 OR+
: 加法-
: 减法*
: 乘法/
: 除法^
: 异或==
: 等于!=
: 不等于>
: 大于<
: 小于>=
: 大于或等于<=
: 小于或等于<<
:IN
>>
:IS
(例如IS NULL
)%
:LIKE
**
:ILIKE
bin_and()
: 二进制 ANDbin_or()
: 二进制 ORin_()
:IN
not_in()
:NOT IN
regexp()
:REGEXP
is_null(True/False)
:IS NULL
或IS NOT NULL
contains(s)
:LIKE %s%
startswith(s)
:LIKE s%
endswith(s)
:LIKE %s
between(low, high)
:BETWEEN low AND high
concat()
:||
- asc([collation=None[, nulls=None]])
- 参数
collation (str) – 用于排序的排序规则名称。
nulls (str) – 排序空值(FIRST 或 LAST)。
- 返回值
一个用于该列的升序
Ordering
对象。
- class Negated(node)
表示一个被否定的列状对象。
- class Value(value[, converterNone[, unpack=True]])
- 参数
value – Python 对象或标量值。
converter – 用于将值转换为数据库理解的类型的函数。
unpack (bool) – 列表或元组是否应解包为值列表或按原样处理。
要在参数化查询中使用的值。调用者有责任确保传入的值可以适应数据库驱动程序理解的类型。
- AsIs(value)
表示一个
Value
,它按原样处理,并直接传递回数据库驱动程序。如果您使用的是接受原生 Python 数据类型的数据库扩展,并且您不希望 Peewee 对值进行任何处理,这可能很有用。
- class Cast(node, cast)
- 参数
node – 列状对象。
cast (str) – 要转换到的类型。
表示一个
CAST(<node> AS <cast>)
表达式。
- class Ordering(node, direction[, collation=None[, nulls=None]])
- 参数
node – 列状对象。
direction (str) – ASC 或 DESC
collation (str) – 用于排序的排序规则名称。
nulls (str) – 排序空值(FIRST 或 LAST)。
表示按列状对象排序。
Postgresql 支持一个非标准子句(“NULLS FIRST/LAST”)。对于不支持此子句的数据库(Sqlite / MySQL),Peewee 会自动使用等效的
CASE
语句。- collate([collation=None])
- 参数
collation (str) – 用于排序的排序规则名称。
- class Expression(lhs, op, rhs[, flat=True])
- 参数
lhs – 左侧。
op – 操作符。
rhs – 右侧。
flat (bool) – 是否用括号包裹表达式。
表示形式为 (lhs op rhs) 的二元表达式,例如 (foo + 1)。
- class Entity(*path)
- 参数
path – 构成实体名称的点分路径的组件。
表示查询中的带引号的实体,例如表、列、别名。名称可能包含多个组件,例如“a_table”.”column_name”。
- __getattr__(self, attr)
创建子实体的工厂方法。
- class SQL(sql[, params=None])
- 参数
sql (str) – SQL 查询字符串。
params (tuple) – 查询参数(可选)。
表示参数化的 SQL 查询或查询片段。
- Check(constraint[, name=None])
- 参数
constraint (str) – 约束 SQL。
name (str) – 约束名称。
表示 CHECK 约束。
警告
MySQL 在将约束与列定义一起内联时可能不支持
name
参数。解决方案是将命名的Check
约束放在模型的Meta.constraints
列表中,而不是放在字段实例的constraints=[...]
列表中。
- class Function(name, arguments[, coerce=True[, python_value=None]])
- 参数
name (str) – 函数名称。
arguments (tuple) – 函数参数。
coerce (bool) – 从游标读取函数返回值时,是否将函数结果强制转换为特定数据类型。
python_value (callable) – 用于转换游标返回的返回值的函数。
表示任意 SQL 函数调用。
注意
建议使用
fn
助手,而不是直接实例化此类。使用
fn
调用任意 SQL 函数的示例# Query users and count of tweets authored. query = (User .select(User.username, fn.COUNT(Tweet.id).alias('ct')) .join(Tweet, JOIN.LEFT_OUTER, on=(User.id == Tweet.user_id)) .group_by(User.username) .order_by(fn.COUNT(Tweet.id).desc()))
- over([partition_by=None[, order_by=None[, start=None[, end=None[, window=None[, exclude=None]]]]]])
- 参数
注意
有关使用 Peewee 的窗口函数的深入指南,请参阅 窗口函数 部分。
示例
# Using a simple partition on a single column. query = (Sample .select( Sample.counter, Sample.value, fn.AVG(Sample.value).over([Sample.counter])) .order_by(Sample.counter)) # Equivalent example Using a Window() instance instead. window = Window(partition_by=[Sample.counter]) query = (Sample .select( Sample.counter, Sample.value, fn.AVG(Sample.value).over(window)) .window(window) # Note call to ".window()" .order_by(Sample.counter)) # Example using bounded window. query = (Sample .select(Sample.value, fn.SUM(Sample.value).over( partition_by=[Sample.counter], start=Window.CURRENT_ROW, # current row end=Window.following())) # unbounded following .order_by(Sample.id))
- filter(where)
- 参数
where – 用于过滤聚合的表达式。
向聚合函数添加
FILTER (WHERE...)
子句。where 表达式用于确定哪些行被馈送到聚合函数。此 SQL 功能受 Postgres 和 SQLite 支持。
- coerce([coerce=True])
- 参数
coerce (bool) – 是否尝试将函数调用结果强制转换为 Python 数据类型。
当 coerce 为
True
时,目标数据类型是使用几种启发式方法推断出来的。阅读BaseModelCursorWrapper._initialize_columns
方法的源代码以了解其工作原理。
- python_value([func=None])
- 参数
python_value (callable) – 用于转换游标返回的返回值的函数。
指定在转换数据库游标返回的值时要使用的特定函数。例如
# Get user and a list of their tweet IDs. The tweet IDs are # returned as a comma-separated string by the db, so we'll split # the result string and convert the values to python ints. convert_ids = lambda s: [int(i) for i in (s or '').split(',') if i] tweet_ids = (fn .GROUP_CONCAT(Tweet.id) .python_value(convert_ids)) query = (User .select(User.username, tweet_ids.alias('tweet_ids')) .group_by(User.username)) for user in query: print(user.username, user.tweet_ids) # e.g., # huey [1, 4, 5, 7] # mickey [2, 3, 6] # zaizee []
- fn()
fn()
助手实际上是Function
的一个实例,它实现了__getattr__
钩子,为调用 SQL 函数提供了一个不错的 API。要创建表示 SQL 函数调用的节点,请使用函数名称作为
fn
上的属性,然后像调用 Python 函数一样提供参数# List users and the number of tweets they have authored, # from highest-to-lowest: sql_count = fn.COUNT(Tweet.id) query = (User .select(User, sql_count.alias('count')) .join(Tweet, JOIN.LEFT_OUTER) .group_by(User) .order_by(sql_count.desc())) # Get the timestamp of the most recent tweet: query = Tweet.select(fn.MAX(Tweet.timestamp)) max_timestamp = query.scalar() # Retrieve scalar result from query.
函数调用可以像其他任何东西一样进行组合和嵌套
# Get users whose username begins with "A" or "a": a_users = User.select().where(fn.LOWER(fn.SUBSTR(User.username, 1, 1)) == 'a')
- class Window([partition_by=None[, order_by=None[, start=None[, end=None[, frame_type=None[, extends=None[, exclude=None[, alias=None]]]]]]])
- 参数
partition_by (list) – 要按其进行分区的列列表。
order_by (list) – 要按其进行排序的列列表。
start – 一个
SQL
实例或表示窗口范围开始的字符串。end – 一个
SQL
实例或表示窗口范围结束的字符串。frame_type (str) –
Window.RANGE
、Window.ROWS
或Window.GROUPS
。extends – 要扩展的
Window
定义。或者,您可以指定窗口的别名。exclude – 帧排除,
Window.CURRENT_ROW
、Window.GROUP
、Window.TIES
或Window.NO_OTHERS
之一。alias (str) – 窗口的别名。
表示 WINDOW 子句。
注意
有关使用 Peewee 的窗口函数的深入指南,请参阅 窗口函数 部分。
- RANGE
- ROWS
- GROUPS
指定窗口
frame_type
。请参阅 帧类型:RANGE vs ROWS vs GROUPS.
- CURRENT_ROW
引用当前行,用于在开始/结束子句或帧排除参数中使用。
- NO_OTHERS
- GROUP
- TIES
指定窗口帧排除参数。
- static preceding([value=None])
- 参数
value – 前面的行数。如果为
None
,则为 UNBOUNDED。
用于生成适合作为窗口范围的
start
参数传递的 SQL 的便捷方法。
- static following([value=None])
- 参数
value – 后面的行数。如果为
None
,则为 UNBOUNDED。
用于生成适合作为窗口范围的
end
参数传递的 SQL 的便捷方法。
- as_rows()
- as_range()
- as_groups()
指定帧类型。
- exclude([frame_exclusion=None])
- 参数
frame_exclusion – 帧排除,可以是
Window.CURRENT_ROW
、Window.GROUP
、Window.TIES
或Window.NO_OTHERS
。
- alias([alias=None])
- 参数
alias (str) – 用于窗口的别名。
- Case(predicate, expression_tuples[, default=None]])
- 参数
predicate – CASE 查询的谓词(可选)。
expression_tuples – 一个或多个要评估的 case。
default – 默认值(可选)。
- 返回值
CASE 语句的表示。
示例
Number = Table('numbers', ('val',)) num_as_str = Case(Number.val, ( (1, 'one'), (2, 'two'), (3, 'three')), 'a lot') query = Number.select(Number.val, num_as_str.alias('num_str')) # The above is equivalent to: # SELECT "val", # CASE "val" # WHEN 1 THEN 'one' # WHEN 2 THEN 'two' # WHEN 3 THEN 'three' # ELSE 'a lot' END AS "num_str" # FROM "numbers" num_as_str = Case(None, ( (Number.val == 1, 'one'), (Number.val == 2, 'two'), (Number.val == 3, 'three')), 'a lot') query = Number.select(Number.val, num_as_str.alias('num_str')) # The above is equivalent to: # SELECT "val", # CASE # WHEN "val" = 1 THEN 'one' # WHEN "val" = 2 THEN 'two' # WHEN "val" = 3 THEN 'three' # ELSE 'a lot' END AS "num_str" # FROM "numbers"
- class NodeList(nodes[, glue=' '[, parens=False]])
- 参数
nodes (list) – 零个或多个节点。
glue (str) – 将节点转换为 SQL 时如何连接节点。
parens (bool) – 是否将生成的 SQL 包含在括号中。
表示节点列表、多部分子句、参数列表等。
- class DQ(**query)
- 参数
query – 使用 Django 风格查找的任意过滤器表达式。
表示可组合的 Django 风格过滤器表达式,适合与
Model.filter()
或ModelSelect.filter()
方法一起使用。
- class OnConflict([action=None[, update=None[, preserve=None[, where=None[, conflict_target=None[, conflict_where=None[, conflict_constraint=None]]]]]]])
- 参数
action (str) – 解决冲突时要采取的操作。
update – 将列映射到新值的字典。
preserve – 列的列表,其值应从原始 INSERT 中保留。另请参阅
EXCLUDED
.where – 用于限制冲突解决的表达式。
conflict_target – 构成约束的列。
conflict_where – 如果约束目标是部分索引(带有 WHERE 子句的索引),则需要匹配约束目标的表达式。
conflict_constraint (str) – 用于冲突解决的约束名称。目前仅受 Postgres 支持。
表示数据修改查询的冲突解决子句。
根据所使用的数据库驱动程序,可能需要上述参数中的一个或多个。
- preserve(*columns)
- 参数
columns – 应保留其值的列。
- update([_data=None[, **kwargs]])
- 参数
_data (dict) – 将列映射到新值的字典。
kwargs – 将列名映射到新值的字典。
The
update()
方法支持使用列到值的字典或表示相同内容的关键字参数调用。
- where(*expressions)
- 参数
expressions – 限制冲突解决子句操作的表达式。
- conflict_target(*constraints)
- 参数
constraints – 用作冲突解决目标的列。
- conflict_where(*expressions)
- 参数
expressions – 匹配冲突目标索引的表达式,如果冲突目标是部分索引。
- conflict_constraint(constraint)
- 参数
constraint (str) – 用作冲突解决目标的约束名称。目前仅受 Postgres 支持。
- class EXCLUDED
辅助对象,公开
EXCLUDED
命名空间,该命名空间与INSERT ... ON CONFLICT
一起使用,用于引用冲突数据中的值。这是一个“神奇”的助手,因此可以通过访问其上与特定列相对应的属性来使用它。示例
class KV(Model): key = CharField(unique=True) value = IntegerField() # Create one row. KV.create(key='k1', value=1) # Demonstrate usage of EXCLUDED. # Here we will attempt to insert a new value for a given key. If that # key already exists, then we will update its value with the *sum* of its # original value and the value we attempted to insert -- provided that # the new value is larger than the original value. query = (KV.insert(key='k1', value=10) .on_conflict(conflict_target=[KV.key], update={KV.value: KV.value + EXCLUDED.value}, where=(EXCLUDED.value > KV.value))) # Executing the above query will result in the following data being # present in the "kv" table: # (key='k1', value=11) query.execute() # If we attempted to execute the query *again*, then nothing would be # updated, as the new value (10) is now less than the value in the # original row (11).
- class BaseQuery
所有其他查询类都派生自的父类。虽然您不会在代码中直接处理
BaseQuery
,但它实现了一些在所有查询类型中通用的方法。- default_row_type = ROW.DICT
- dicts([as_dict=True])
- 参数
as_dict (bool) – 指定是否将行作为字典返回。
将行作为字典返回。
- tuples([as_tuples=True])
- 参数
as_tuple (bool) – 指定是否将行作为元组返回。
将行作为元组返回。
- namedtuples([as_namedtuple=True])
- 参数
as_namedtuple (bool) – 指定是否将行作为命名元组返回。
将行作为命名元组返回。
- objects([constructor=None])
- 参数
constructor – 接受行字典并返回任意对象的函数。
使用给定的构造函数将行作为任意对象返回。
- sql()
- 返回值
包含查询的 SQL 和参数的 2 元组。
- execute(database)
- 参数
database (Database) – 要执行查询的数据库。如果查询之前已绑定到数据库,则不需要。
执行查询并返回结果(取决于正在执行的查询类型)。例如,选择查询的返回结果将是查询结果的迭代器。
- iterator([database=None])
- 参数
database (Database) – 要执行查询的数据库。如果查询之前已绑定到数据库,则不需要。
执行查询并返回结果集的迭代器。对于大型结果集,此方法更可取,因为行在迭代期间不会缓存在内存中。
注意
由于行不会被缓存,因此查询只能迭代一次。后续迭代将返回空结果集,因为游标将被消耗。
示例
query = StatTbl.select().order_by(StatTbl.timestamp).tuples() for row in query.iterator(db): process_row(row)
- __iter__()
执行查询并返回结果集的迭代器。
与
iterator()
不同,此方法将导致行被缓存以允许高效迭代、索引和切片。
- __getitem__(value)
- 参数
value – 整数索引或切片。
从结果集中检索一行或一系列行。
- __len__()
返回结果集中的行数。
警告
这不会发出
COUNT()
查询。相反,结果集将按在正常迭代期间的方式加载,并且长度将根据结果集的大小确定。
- class RawQuery([sql=None[, params=None[, **kwargs]]])
- 参数
sql (str) – SQL 查询。
params (tuple) – 参数(可选)。
通过直接指定要执行的 SQL 来创建查询。
- class Query([where=None[, order_by=None[, limit=None[, offset=None[, **kwargs]]]]])
- 参数
where – WHERE 子句的表示。
order_by (tuple) – 要排序的列或值。
limit (int) – LIMIT 子句的值。
offset (int) – OFFSET 子句的值。
支持方法链 API 的查询的基类。
- with_cte(*cte_list)
- 参数
cte_list – 零个或多个
CTE
对象。
在查询中包含给定的公用表表达式。任何先前指定的 CTE 都将被覆盖。有关公用表表达式的示例,请参阅 公用表表达式。
- cte(name[, recursive=False[, columns=None]])
- 参数
name (str) – 公用表表达式的别名。
recursive (bool) – 这将是一个递归 CTE 吗?
columns (list) – 列名称列表(作为字符串)。
指示查询将用作公用表表达式。例如,如果我们正在对类别树进行建模并使用父链接外键,我们可以使用递归 CTE 检索所有类别及其绝对深度
class Category(Model): name = TextField() parent = ForeignKeyField('self', backref='children', null=True) # The base case of our recursive CTE will be categories that are at # the root level -- in other words, categories without parents. roots = (Category .select(Category.name, Value(0).alias('level')) .where(Category.parent.is_null()) .cte(name='roots', recursive=True)) # The recursive term will select the category name and increment # the depth, joining on the base term so that the recursive term # consists of all children of the base category. RTerm = Category.alias() recursive = (RTerm .select(RTerm.name, (roots.c.level + 1).alias('level')) .join(roots, on=(RTerm.parent == roots.c.id))) # Express <base term> UNION ALL <recursive term>. cte = roots.union_all(recursive) # Select name and level from the recursive CTE. query = (cte .select_from(cte.c.name, cte.c.level) .order_by(cte.c.name)) for category in query: print(category.name, category.level)
有关 CTE 的更多示例,请参阅 公用表表达式。
- where(*expressions)
- 参数
expressions – 要包含在 WHERE 子句中的零个或多个表达式。
在查询的 WHERE 子句中包含给定的表达式。这些表达式将与任何先前指定的 WHERE 表达式进行 AND 连接。
选择用户名等于“somebody”的用户的示例
sq = User.select().where(User.username == 'somebody')
选择由编辑或管理员发布的推文的示例
sq = Tweet.select().join(User).where( (User.is_editor == True) | (User.is_admin == True))
删除不再活跃的用户的推文的示例
inactive_users = User.select().where(User.active == False) dq = (Tweet .delete() .where(Tweet.user.in_(inactive_users))) dq.execute() # Return number of tweets deleted.
注意
where()
调用是可链的。多个调用将被“AND”连接在一起。
- orwhere(*expressions)
- 参数
expressions – 要包含在 WHERE 子句中的零个或多个表达式。
在查询的 WHERE 子句中包含给定的表达式。此方法与
Query.where()
方法相同,只是表达式将与之前指定的任何 WHERE 表达式进行 OR 操作。
- order_by(*values)
- 参数
values – 一个或多个用于排序的类似 Column 的对象。
定义 ORDER BY 子句。任何之前指定的 value 将被覆盖。
- order_by_extend(*values)
- 参数
values – 一个或多个用于排序的类似 Column 的对象。
使用给定的 value 扩展之前指定的任何 ORDER BY 子句。
- limit([value=None])
- 参数
value (int) – 指定 LIMIT 子句的值。
- offset([value=None])
- 参数
value (int) – 指定 OFFSET 子句的值。
- paginate(page[, paginate_by=20])
- 参数
page (int) – 结果的页码(从 1 开始)。
paginate_by (int) – 每页行数。
用于以更直观的方式指定 LIMIT 和 OFFSET 的便捷方法。
此功能旨在用于网站分页,因此第一页从
page=1
开始。
- class SelectQuery
Select 查询辅助类,它实现了运算符重载,用于创建复合查询。
- select_from(*columns)
- 参数
columns – 从内部查询中选择的列。
- 返回值
一个包装调用查询的新查询。
创建一个包装当前(调用)查询的新查询。例如,假设您有一个简单的
UNION
查询,并且需要对联合结果集应用聚合。为此,您需要编写类似以下内容SELECT "u"."owner", COUNT("u"."id") AS "ct" FROM ( SELECT "id", "owner", ... FROM "cars" UNION SELECT "id", "owner", ... FROM "motorcycles" UNION SELECT "id", "owner", ... FROM "boats") AS "u" GROUP BY "u"."owner"
The
select_from()
方法旨在简化此类查询的构建。示例 peewee 代码
class Car(Model): owner = ForeignKeyField(Owner, backref='cars') # ... car-specific fields, etc ... class Motorcycle(Model): owner = ForeignKeyField(Owner, backref='motorcycles') # ... motorcycle-specific fields, etc ... class Boat(Model): owner = ForeignKeyField(Owner, backref='boats') # ... boat-specific fields, etc ... cars = Car.select(Car.owner) motorcycles = Motorcycle.select(Motorcycle.owner) boats = Boat.select(Boat.owner) union = cars | motorcycles | boats query = (union .select_from(union.c.owner, fn.COUNT(union.c.id)) .group_by(union.c.owner))
- union_all(dest)
使用
dest
创建一个 UNION ALL 查询。
- __add__(dest)
使用
dest
创建一个 UNION ALL 查询。
- union(dest)
使用
dest
创建一个 UNION 查询。
- __or__(dest)
使用
dest
创建一个 UNION 查询。
- intersect(dest)
使用
dest
创建一个 INTERSECT 查询。
- __and__(dest)
使用
dest
创建一个 INTERSECT 查询。
- except_(dest)
使用
dest
创建一个 EXCEPT 查询。请注意,方法名称末尾有一个“_”字符,因为except
是 Python 保留字。
- __sub__(dest)
使用
dest
创建一个 EXCEPT 查询。
- class SelectBase
Select
和CompoundSelect
查询的基类。- peek(database[, n=1])
- 参数
database (Database) – 要执行查询的数据库。
n (int) – 要返回的行数。
- 返回值
如果 n = 1,则为单行,否则为行列表。
执行查询并从游标的开头返回给定数量的行。此函数可以安全地多次调用,并且始终返回结果的前 N 行。
- first(database[, n=1])
- 参数
database (Database) – 要执行查询的数据库。
n (int) – 要返回的行数。
- 返回值
如果 n = 1,则为单行,否则为行列表。
类似于
peek()
方法,只是对查询应用了LIMIT
以确保仅返回n
行。对相同n
值的多次调用不会导致多次执行。查询在原地被修改,因此无法调用
first()
然后使用相同的查询对象遍历完整的结果集。同样,这样做是为了确保对first()
的多次调用不会导致多次查询执行。
- scalar(database[, as_tuple=False[, as_dict=False]])
- 参数
database (Database) – 要执行查询的数据库。
as_tuple (bool) – 将结果作为元组返回?
as_dict (bool) – 将结果作为字典返回?
- 返回值
单个标量值。如果
as_tuple = True
,则返回行元组。如果as_dict = True
,则返回行字典。
从结果集的第一行返回一个标量值。如果预期多个标量值(例如,单个查询中的多个聚合),则可以指定
as_tuple=True
以获取行元组。示例
query = Note.select(fn.MAX(Note.timestamp)) max_ts = query.scalar(db) query = Note.select(fn.MAX(Note.timestamp), fn.COUNT(Note.id)) max_ts, n_notes = query.scalar(db, as_tuple=True) query = Note.select(fn.COUNT(Note.id).alias('count')) assert query.scalar(db, as_dict=True) == {'count': 123}
- class CompoundSelectQuery(lhs, op, rhs)
- 参数
lhs (SelectBase) – Select 或 CompoundSelect 查询。
op (str) – 操作(例如 UNION、INTERSECT、EXCEPT)。
rhs (SelectBase) – Select 或 CompoundSelect 查询。
表示复合 SELECT 查询的类。
- class Select([from_list=None[, columns=None[, group_by=None[, having=None[, distinct=None[, windows=None[, for_update=None[, for_update_of=None[, for_update_nowait=None[, **kwargs]]]]]]]]])
- 参数
from_list (list) – FROM 子句的来源列表。
columns (list) – 要选择的列或值。
group_by (list) – 要分组的列或值的列表。
having (Expression) – HAVING 子句的表达式。
distinct – 布尔值或列状对象列表。
windows (list) –
Window
子句列表。for_update – 布尔值或字符串,指示是否使用 SELECT…FOR UPDATE。
for_update_of – FOR UPDATE OF 子句的一个或多个表。
for_update_nowait (bool) – 指定 NOWAIT 锁定。
表示 SELECT 查询的类。
注意
通常,您不会直接实例化它,而是使用工厂方法,例如
Table.select()
或Model.select()
。可以在 select 查询上链接方法。
从数据库中选择一些用户实例的示例。仅选择
id
和username
列。迭代时,将返回User
模型的实例query = User.select(User.id, User.username) for user in query: print(user.username)
选择用户以及用户发布的推文数量的示例。返回的
User
实例将具有一个额外的属性“count”,它对应于发布的推文数量query = (User .select(User, fn.COUNT(Tweet.id).alias('count')) .join(Tweet, JOIN.LEFT_OUTER) .group_by(User)) for user in query: print(user.username, 'has tweeted', user.count, 'times')
注意
虽然可以直接实例化
Select
,但更常见的是使用方法链 API 来构建查询。- columns(*columns)
- 参数
columns – 要 SELECT 的零个或多个列状对象。
指定要 SELECT 的列或列状值。
- select(*columns)
- 参数
columns – 要 SELECT 的零个或多个列状对象。
与
Select.columns()
相同,为了向后兼容而提供。
- select_extend(*columns)
- 参数
columns – 要 SELECT 的零个或多个列状对象。
使用给定的列扩展当前选择。
示例
def get_users(with_count=False): query = User.select() if with_count: query = (query .select_extend(fn.COUNT(Tweet.id).alias('count')) .join(Tweet, JOIN.LEFT_OUTER) .group_by(User)) return query
- from_(*sources)
- 参数
sources – FROM 子句的零个或多个来源。
指定 FROM 子句中应使用哪些表状对象。
User = Table('users') Tweet = Table('tweets') query = (User .select(User.c.username, Tweet.c.content) .from_(User, Tweet) .where(User.c.id == Tweet.c.user_id)) for row in query.execute(db): print(row['username'], '->', row['content'])
- join(dest[, join_type='INNER'[, on=None]])
- 参数
dest – 表或表状对象。
join_type (str) – JOIN 类型,默认为“INNER”。
on (Expression) – 连接谓词。
联接类型可以是以下之一
JOIN.INNER
JOIN.LEFT_OUTER
JOIN.RIGHT_OUTER
JOIN.FULL
JOIN.FULL_OUTER
JOIN.CROSS
表达 JOIN
User = Table('users', ('id', 'username')) Note = Table('notes', ('id', 'user_id', 'content')) query = (Note .select(Note.content, User.username) .join(User, on=(Note.user_id == User.id)))
- group_by(*columns)
- 参数
values – 要分组的零个或多个 Column 状对象。
定义 GROUP BY 子句。任何先前指定的 value 将被覆盖。
此外,要指定给定表上的所有列,可以将表/模型对象传递给单个列。
示例
query = (User .select(User, fn.Count(Tweet.id).alias('count')) .join(Tweet) .group_by(User))
- group_by_extend(*columns)
- 参数
values – 要分组的零个或多个 Column 状对象。
使用给定的列扩展 GROUP BY 子句。
- having(*expressions)
- 参数
expressions – 要包含在 HAVING 子句中的零个或多个表达式。
将给定的表达式包含在查询的 HAVING 子句中。这些表达式将与任何先前指定的 HAVING 表达式进行 AND 操作。
- distinct(*columns)
- 参数
columns – 零个或多个列状对象。
指示此查询是否应使用 DISTINCT 子句。通过指定单个
True
值,查询将使用简单的 SELECT DISTINCT。指定一个或多个列将导致 SELECT DISTINCT ON。
- window(*windows)
- 参数
windows – 零个或多个
Window
对象。
定义 WINDOW 子句。任何先前指定的 value 将被覆盖。
示例
# Equivalent example Using a Window() instance instead. window = Window(partition_by=[Sample.counter]) query = (Sample .select( Sample.counter, Sample.value, fn.AVG(Sample.value).over(window)) .window(window) # Note call to ".window()" .order_by(Sample.counter))
- for_update([for_update=True[, of=None[, nowait=None]]])
- 参数
for_update – 布尔值或字符串,指示所需的表达式,例如“FOR SHARE”。
of – 要限制锁定的一个或多个模型。
nowait (bool) – 锁定时指定 NOWAIT 选项。
- class _WriteQuery(table[, returning=None[, **kwargs]])
- 参数
table (Table) – 要写入的表。
returning (list) – RETURNING 子句的列列表。
写入查询的基类。
- returning(*returning)
- 参数
returning – RETURNING 子句的零个或多个列状对象
指定查询的 RETURNING 子句(如果您的数据库支持)。
query = (User .insert_many([{'username': 'foo'}, {'username': 'bar'}, {'username': 'baz'}]) .returning(User.id, User.username) .namedtuples()) data = query.execute() for row in data: print('added:', row.username, 'with id=', row.id)
- class Update(table[, update=None[, **kwargs]])
- 参数
table (Table) – 要更新的表格。
update (dict) – 要更新的数据。
表示 UPDATE 查询的类。
示例
PageView = Table('page_views') query = (PageView .update({PageView.c.page_views: PageView.c.page_views + 1}) .where(PageView.c.url == url)) query.execute(database)
- from_(*sources)
- 参数
sources (Source) – 一个或多个
Table
、Model
、查询或ValuesList
,用于连接。
使用 UPDATE … FROM 语法指定要连接的额外表格,该语法受 Postgres 支持。 Postgres 文档 提供了更多详细信息,但总结一下
当存在
FROM
子句时,实际上发生的是目标表格与 from_list 中提到的表格连接,并且连接的每个输出行代表对目标表格的更新操作。 使用FROM
时,应确保连接为每个要修改的行最多产生一个输出行。示例
# Update multiple users in a single query. data = [('huey', True), ('mickey', False), ('zaizee', True)] vl = ValuesList(data, columns=('username', 'is_admin'), alias='vl') # Here we'll update the "is_admin" status of the above users, # "joining" the VALUES() on the "username" column. query = (User .update(is_admin=vl.c.is_admin) .from_(vl) .where(User.username == vl.c.username))
上面的查询产生以下 SQL
UPDATE "users" SET "is_admin" = "vl"."is_admin" FROM ( VALUES ('huey', t), ('mickey', f), ('zaizee', t)) AS "vl"("username", "is_admin") WHERE ("users"."username" = "vl"."username")
- class Insert(table[, insert=None[, columns=None[, on_conflict=None[, **kwargs]]]])
- 参数
table (Table) – 要插入数据的表格。
insert – 字典、列表或查询。
columns (list) – 当
insert
是列表或查询时,列的列表。on_conflict – 冲突解决策略。
表示 INSERT 查询的类。
- as_rowcount([as_rowcount=True])
- 参数
as_rowcount (bool) – 是否返回修改的行数(而不是最后插入的行 ID)。
默认情况下,在不使用 RETURNING 自动化的数据库(目前为 Sqlite 和 MySQL)上,Peewee 版本 3.12 到 3.14.10 在执行批量插入时将返回修改的行数。 此更改已恢复,因此批量插入默认情况下将返回
cursor.lastrowid
的值。如果您希望接收插入的行数,请指定
as_rowcount()
db = MySQLDatabase(...) query = User.insert_many([...]) # By default, the last rowid is returned: #last_id = query.execute() # To get the modified row-count: rowcount = query.as_rowcount().execute()
- on_conflict_ignore([ignore=True])
- 参数
ignore (bool) – 是否添加 ON CONFLICT IGNORE 子句。
指定 IGNORE 冲突解决策略。
- on_conflict_replace([replace=True])
- 参数
replace (bool) – 是否添加 ON CONFLICT REPLACE 子句。
指定 REPLACE 冲突解决策略。
- on_conflict([action=None[, update=None[, preserve=None[, where=None[, conflict_target=None[, conflict_where=None[, conflict_constraint=None]]]]]]])
- 参数
action (str) – 解决冲突时要采取的操作。 如果为空,则操作被假定为“update”。
update – 将列映射到新值的字典。
preserve – 一列列出应从原始 INSERT 中保留其值的列。
where – 用于限制冲突解决的表达式。
conflict_target – 构成约束的列。
conflict_where – 如果约束目标是部分索引(带有 WHERE 子句的索引),则需要匹配约束目标的表达式。
conflict_constraint (str) – 用于冲突解决的约束名称。目前仅受 Postgres 支持。
指定用于冲突解决的
OnConflict
子句的参数。示例
class User(Model): username = TextField(unique=True) last_login = DateTimeField(null=True) login_count = IntegerField() def log_user_in(username): now = datetime.datetime.now() # INSERT a new row for the user with the current timestamp and # login count set to 1. If the user already exists, then we # will preserve the last_login value from the "insert()" clause # and atomically increment the login-count. userid = (User .insert(username=username, last_login=now, login_count=1) .on_conflict( conflict_target=[User.username], preserve=[User.last_login], update={User.login_count: User.login_count + 1}) .execute()) return userid
使用特殊
EXCLUDED
命名空间的示例class KV(Model): key = CharField(unique=True) value = IntegerField() # Create one row. KV.create(key='k1', value=1) # Demonstrate usage of EXCLUDED. # Here we will attempt to insert a new value for a given key. If that # key already exists, then we will update its value with the *sum* of its # original value and the value we attempted to insert -- provided that # the new value is larger than the original value. query = (KV.insert(key='k1', value=10) .on_conflict(conflict_target=[KV.key], update={KV.value: KV.value + EXCLUDED.value}, where=(EXCLUDED.value > KV.value))) # Executing the above query will result in the following data being # present in the "kv" table: # (key='k1', value=11) query.execute() # If we attempted to execute the query *again*, then nothing would be # updated, as the new value (10) is now less than the value in the # original row (11).
- class Delete
表示 DELETE 查询的类。
- class Index(name, table, expressions[, unique=False[, safe=False[, where=None[, using=None]]]])
- 参数
name (str) – 索引名称。
table (Table) – 要创建索引的表格。
expressions – 要索引的列(或表达式)的列表。
unique (bool) – 索引是否为 UNIQUE。
safe (bool) – 是否添加 IF NOT EXISTS 子句。
where (Expression) – 索引的可选 WHERE 子句。
using (str) – 索引算法。
- safe([_safe=True])
- 参数
_safe (bool) – 是否添加 IF NOT EXISTS 子句。
- where(*expressions)
- 参数
expressions – 要包含在 WHERE 子句中的零个或多个表达式。
将给定的表达式包含在索引的 WHERE 子句中。 这些表达式将与任何先前指定的 WHERE 表达式进行 AND 操作。
- using([_using=None])
- 参数
_using (str) – 为 USING 子句指定索引算法。
- class ModelIndex(model, fields[, unique=False[, safe=True[, where=None[, using=None[, name=None]]]]])
- 参数
model (Model) – 要创建索引的模型类。
fields (list) – 要索引的字段。
unique (bool) – 索引是否为 UNIQUE。
safe (bool) – 是否添加 IF NOT EXISTS 子句。
where (Expression) – 索引的可选 WHERE 子句。
using (str) – 索引算法或类型,例如“BRIN”、“GiST”或“GIN”。
name (str) – 可选的索引名称。
用于在模型上声明索引的表达方式。
示例
class Article(Model): name = TextField() timestamp = TimestampField() status = IntegerField() flags = BitField() is_sticky = flags.flag(1) is_favorite = flags.flag(2) # CREATE INDEX ... ON "article" ("name", "timestamp") idx = ModelIndex(Article, (Article.name, Article.timestamp)) # CREATE INDEX ... ON "article" ("name", "timestamp") WHERE "status" = 1 idx = idx.where(Article.status == 1) # CREATE UNIQUE INDEX ... ON "article" ("timestamp" DESC, "flags" & 2) WHERE "status" = 1 idx = ModelIndex( Article, (Article.timestamp.desc(), Article.flags.bin_and(2)), unique = True).where(Article.status == 1)
您也可以使用
Model.index()
idx = Article.index(Article.name, Article.timestamp).where(Article.status == 1)
要将索引添加到模型定义中,请使用
Model.add_index()
idx = Article.index(Article.name, Article.timestamp).where(Article.status == 1) # Add above index definition to the model definition. When you call # Article.create_table() (or database.create_tables([Article])), the # index will be created. Article.add_index(idx)
Fields
- class Field([null=False[, index=False[, unique=False[, column_name=None[, default=None[, primary_key=False[, constraints=None[, sequence=None[, collation=None[, unindexed=False[, choices=None[, help_text=None[, verbose_name=None[, index_type=None]]]]]]]]]]]])
- 参数
null (bool) – 字段允许 NULL 值。
index (bool) – 在字段上创建索引。
unique (bool) – 在字段上创建唯一索引。
column_name (str) – 指定字段的列名。
default – 默认值(在 Python 中强制执行,而不是在服务器上)。
primary_key (bool) – 字段是主键。
constraints (list) – 要应用于列的约束列表,例如:
[Check('price > 0')]
。sequence (str) – 字段的序列名称。
collation (str) – 字段的排序规则名称。
unindexed (bool) – 声明字段 UNINDEXED(仅限 sqlite)。
choices (list) – 一个可迭代的 2 元组列表,将列值映射到显示标签。仅用于元数据目的,以帮助在显示字段值的选项下拉列表时提供帮助,例如。
help_text (str) – 字段的帮助文本,仅用于元数据目的。
verbose_name (str) – 字段的详细名称,仅用于元数据目的。
index_type (str) – 指定索引类型(仅限 postgres),例如 'BRIN'。
模型上的字段类似于表上的列。
- field_type = '<some field type>'
用于将此字段映射到列类型的属性,例如“INT”。有关更多信息,请参阅源代码中的
FIELD
对象。
- model
字段绑定的模型。
- name
字段的名称。
- db_value(value)
将 Python 值强制转换为适合存储在数据库中的值。操作特殊数据类型的子类很可能需要覆盖此方法。
- python_value(value)
将数据库中的值强制转换为 Python 对象。操作特殊数据类型的子类很可能需要覆盖此方法。
- coerce(value)
此方法是简写,默认情况下,它由
db_value()
和python_value()
使用。- 参数
value – 来自应用程序或后端的任意数据
- 返回类型
python 数据类型
- class IntegerField
用于存储整数的字段类。
- class BigIntegerField
用于存储大整数(如果数据库支持)的字段类。
- class SmallIntegerField
用于存储小整数(如果数据库支持)的字段类。
- class AutoField
用于存储自动递增主键的字段类。
注意
在 SQLite 中,出于性能原因,默认主键类型仅使用最大现有值 + 1 来表示新值,而不是使用最大值 + 1。这意味着已删除的记录可以重复使用其主键。结合 SQLite 默认情况下禁用外键(这意味着即使您明确指定,ON DELETE 也会被忽略),这会导致令人惊讶和危险的行为。为了避免这种情况,您可能希望在实例化
SqliteDatabase
时使用AutoIncrementField
和pragmas=[('foreign_keys', 'on')]
中的一个或两个。
- class BigAutoField
用于使用 64 位存储自动递增主键的字段类。
- class IdentityField([generate_always=False])
- 参数
generate_always (bool) – 如果指定,则始终生成标识(并且在 INSERT 期间明确指定值将引发编程错误)。否则,仅在需要时生成标识值。
用于使用新的 Postgres 10 IDENTITY 列类型存储自动递增主键的字段类。列定义最终看起来像这样
id = IdentityField() # "id" INT GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY
注意
仅受 Postgres 10.0 及更高版本支持。
- class FloatField
用于存储浮点数的字段类。
- class DoubleField
用于存储双精度浮点数的字段类。
- class DecimalField([max_digits=10[, decimal_places=5[, auto_round=False[, rounding=None[, **kwargs]]]]])
- 参数
max_digits (int) – 存储的最大位数。
decimal_places (int) – 最大精度。
auto_round (bool) – 自动舍入值。
舍入 –
默认为
decimal.DefaultContext.rounding
。用于存储十进制数字的字段类。值表示为
decimal.Decimal
对象。
- class CharField([max_length=255])
用于存储字符串的字段类。
注意
超过长度的值不会自动截断。
- class FixedCharField
用于存储固定长度字符串的字段类。
注意
超过长度的值不会自动截断。
- class TextField
用于存储文本的字段类。
- class BlobField
用于存储二进制数据的字段类。
- class BitField
用于在 64 位整数列中存储选项的字段类。
用法
class Post(Model): content = TextField() flags = BitField() is_favorite = flags.flag(1) is_sticky = flags.flag(2) is_minimized = flags.flag(4) is_deleted = flags.flag(8) >>> p = Post() >>> p.is_sticky = True >>> p.is_minimized = True >>> print(p.flags) # Prints 4 | 2 --> "6" 6 >>> p.is_favorite False >>> p.is_sticky True
我们也可以使用 Post 类上的标志在查询中构建表达式
# Generates a WHERE clause that looks like: # WHERE (post.flags & 1 != 0) query = Post.select().where(Post.is_favorite) # Query for sticky + favorite posts: query = Post.select().where(Post.is_sticky & Post.is_favorite)
在对
BitField
中的一个或多个位进行批量更新时,可以使用按位运算符来设置或清除一个或多个位# Set the 4th bit on all Post objects. Post.update(flags=Post.flags | 8).execute() # Clear the 1st and 3rd bits on all Post objects. Post.update(flags=Post.flags & ~(1 | 4)).execute()
对于简单的操作,标志提供了方便的
set()
和clear()
方法来设置或清除单个位# Set the "is_deleted" bit on all posts. Post.update(flags=Post.is_deleted.set()).execute() # Clear the "is_deleted" bit on all posts. Post.update(flags=Post.is_deleted.clear()).execute()
- flag([value=None])
- 参数
value (int) – 与标志关联的值,通常为 2 的幂。
返回一个描述符,可以获取或设置整体值中的特定位。当在类本身访问时,它返回一个
Expression
对象,适合在查询中使用。如果没有提供值,则假定每个标志都是 2 的递增幂,因此如果您有四个标志,它们的值将为 1、2、4、8。
- class BigBitField
用于在
BLOB
中存储任意大小位图的字段类。该字段将根据需要扩展底层缓冲区,确保有足够的字节数据来支持正在存储的位数据数量。示例用法
class Bitmap(Model): data = BigBitField() bitmap = Bitmap() # Sets the ith bit, e.g. the 1st bit, the 11th bit, the 63rd, etc. bits_to_set = (1, 11, 63, 31, 55, 48, 100, 99) for bit_idx in bits_to_set: bitmap.data.set_bit(bit_idx) # We can test whether a bit is set using "is_set": assert bitmap.data.is_set(11) assert not bitmap.data.is_set(12) # We can clear a bit: bitmap.data.clear_bit(11) assert not bitmap.data.is_set(11) # We can also "toggle" a bit. Recall that the 63rd bit was set earlier. assert bitmap.data.toggle_bit(63) is False assert bitmap.data.toggle_bit(63) is True assert bitmap.data.is_set(63) # BigBitField supports item accessor by bit-number, e.g.: assert bitmap.data[63] bitmap.data[0] = 1 del bitmap.data[0] # We can also combine bitmaps using bitwise operators, e.g. b = Bitmap(data=b'\x01') b.data |= b'\x02' assert list(b.data) == [1, 1, 0, 0, 0, 0, 0, 0] assert len(b.data) == 1
- clear()
清除位图并将长度设置为 0。
- set_bit(idx)
- 参数
idx (int) – 要设置的位,从零开始索引。
设置位图中的第 idx 位。
- clear_bit(idx)
- 参数
idx (int) – 要清除的位,从零开始索引。
清除位图中的第 idx 位。
- toggle_bit(idx)
- 参数
idx (int) – 要切换的位,从零开始索引。
- 返回值
位是否设置。
切换位图中的第 idx 位,并返回该位是否设置。
示例
>>> bitmap = Bitmap() >>> bitmap.data.toggle_bit(10) # Toggle the 10th bit. True >>> bitmap.data.toggle_bit(10) # This will clear the 10th bit. False
- is_set(idx)
- 参数
idx (int) – 位索引,从零开始索引。
- 返回值
位是否设置。
返回一个布尔值,指示第 idx 位是否设置。
- __setitem__(idx, value)
将
idx
处的位设置为值(True 或 False)。
- __delitem__(idx)
与
clear_bit()
相同
- __len__()
返回位图的长度(以字节为单位)。
- __iter__()
返回一个迭代器,为位图中的每个位生成 1 或 0。
- __and__(other)
- 参数
other –
BigBitField
、bytes
、bytearray
或memoryview
对象。- 返回值
两个位图的按位
and
。
- __or__(other)
- 参数
other –
BigBitField
、bytes
、bytearray
或memoryview
对象。- 返回值
两个位图的按位
or
。
- __xor__(other)
- 参数
other –
BigBitField
、bytes
、bytearray
或memoryview
对象。- 返回值
两个位图的按位
xor
。
- class UUIDField
用于存储
uuid.UUID
对象的字段类。使用 Postgres 时,底层列的数据类型将为 UUID。由于 SQLite 和 MySQL 没有原生 UUID 类型,因此 UUID 存储为 VARCHAR。
- class BinaryUUIDField
用于在 16 个字节中高效存储
uuid.UUID
对象的字段类。使用数据库的 BLOB 数据类型(或 MySQL 中的 VARBINARY,或 Postgres 中的 BYTEA)。
- class DateTimeField([formats=None[, **kwargs]])
- 参数
formats (list) – 将字符串强制转换为日期时间时要使用的格式字符串列表。
用于存储
datetime.datetime
对象的字段类。接受一个特殊的参数
formats
,它包含一个日期时间可以编码的格式列表(对于不支持原生日期时间数据类型的数据库)。默认支持的格式是'%Y-%m-%d %H:%M:%S.%f' # year-month-day hour-minute-second.microsecond '%Y-%m-%d %H:%M:%S' # year-month-day hour-minute-second '%Y-%m-%d' # year-month-day
注意
SQLite 没有原生日期时间数据类型,因此日期时间存储为字符串。Peewee 透明地处理了这一点,但如果您有预先存在的数据,您应该确保它存储为
YYYY-mm-dd HH:MM:SS
或其他支持的格式之一。- year
在查询中引用存储在列中的值的年份。
Blog.select().where(Blog.pub_date.year == 2018)
- month
在查询中引用存储在列中的值的月份。
- day
在查询中引用存储在列中的值的天数。
- hour
在查询中引用存储在列中的值的小时。
- minute
在查询中引用存储在列中的值的分钟。
- second
在查询中引用存储在列中的值的秒数。
- to_timestamp()
该方法返回一个数据库特定的函数调用,允许您将给定的日期时间值作为数字时间戳处理。这有时可以以兼容的方式简化日期数学等任务。
示例
# Find all events that are exactly 1 hour long. query = (Event .select() .where((Event.start.to_timestamp() + 3600) == Event.stop.to_timestamp()) .order_by(Event.start))
- truncate(date_part)
- 参数
date_part (str) – 年、月、日、时、分或秒。
- 返回值
表达式节点,用于将日期/时间截断到给定的分辨率。
将列中的值截断到给定的部分。此方法对于查找给定月份内的所有行很有用,例如。
- class DateField([formats=None[, **kwargs]])
- 参数
formats (list) – 将字符串强制转换为日期时使用的格式字符串列表。
用于存储
datetime.date
对象的字段类。接受一个特殊的参数
formats
,它包含一个日期时间可以编码的格式列表(对于不支持原生日期数据类型的数据库)。默认支持的格式是'%Y-%m-%d' # year-month-day '%Y-%m-%d %H:%M:%S' # year-month-day hour-minute-second '%Y-%m-%d %H:%M:%S.%f' # year-month-day hour-minute-second.microsecond
注意
如果传入的值与任何格式都不匹配,则按原样返回。
- year
在查询中引用存储在列中的值的年份。
Person.select().where(Person.dob.year == 1983)
- month
在查询中引用存储在列中的值的月份。
- day
在查询中引用存储在列中的值的天数。
- to_timestamp()
- truncate(date_part)
参见
DateTimeField.truncate()
。请注意,对于DateField
,只有 year、month 和 day 有意义。
- class TimeField([formats=None[, **kwargs]])
- 参数
formats (list) – 将字符串强制转换为时间时使用的格式字符串列表。
用于存储
datetime.time
对象(而不是timedelta
)的字段类。接受一个特殊的参数
formats
,它包含一个日期时间可以编码的格式列表(对于不支持原生时间数据类型的数据库)。默认支持的格式是'%H:%M:%S.%f' # hour:minute:second.microsecond '%H:%M:%S' # hour:minute:second '%H:%M' # hour:minute '%Y-%m-%d %H:%M:%S.%f' # year-month-day hour-minute-second.microsecond '%Y-%m-%d %H:%M:%S' # year-month-day hour-minute-second
注意
如果传入的值与任何格式都不匹配,则按原样返回。
- hour
在查询中引用存储在列中的值的小时。
evening_events = Event.select().where(Event.time.hour > 17)
- minute
在查询中引用存储在列中的值的分钟。
- second
在查询中引用存储在列中的值的秒数。
- class TimestampField([resolution=1[, utc=False[, **kwargs]]])
- 参数
resolution – 可以提供为 10 的幂,也可以提供为指数,表示要存储的小数位数。
utc (bool) – 将时间戳视为 UTC。
用于将日期时间存储为整数时间戳的字段类。通过乘以 10 的幂来获得整数,支持亚秒分辨率。
如果
resolution
参数为0
或1
,则时间戳使用秒分辨率存储。介于2
和6
之间的分辨率被视为小数位数,例如resolution=3
对应于毫秒。或者,小数可以提供为 10 的倍数,这样resolution=10
将存储 1/10 秒分辨率。该
resolution
参数可以是 0-6 或 10、100 等,直到 1000000(对于微秒分辨率)。这允许亚秒精度,同时仍然使用IntegerField
进行存储。默认值为秒分辨率。还接受一个布尔参数
utc
,用于指示时间戳是否应为 UTC。默认值为False
。最后,字段
default
是当前时间戳。如果您不希望这种行为,则明确传入default=None
。
- class IPField
用于有效存储 IPv4 地址(作为整数)的字段类。
- class BooleanField
用于存储布尔值的字段类。
- class BareField([coerce=None[, **kwargs]])
- 参数
coerce – 可选函数,用于将原始值转换为特定格式。
不指定数据类型的字段类(**仅限 SQLite**)。
由于数据类型不受强制,因此您可以声明没有任何数据类型的字段。 SQLite 虚拟表通常使用元列或无类型列,因此在这些情况下,您可能也希望使用无类型字段。
接受一个特殊的
coerce
参数,该参数是一个函数,它接受来自数据库的值并将其转换为适当的 Python 类型。
- class ForeignKeyField(model[, field=None[, backref=None[, on_delete=None[, on_update=None[, deferrable=None[, object_id_name=None[, lazy_load=True[, constraint_name=None[, **kwargs]]]]]]]])
- 参数
model (Model) – 要引用的模型,如果声明自引用外键,则为字符串“self”。
field (Field) – 要在
model
上引用的字段(默认为主键)。backref (str) – 反向引用的访问器名称,或“+”以禁用反向引用访问器。
on_delete (str) – ON DELETE 操作,例如
'CASCADE'
。on_update (str) – ON UPDATE 操作。
deferrable (str) – 控制何时强制约束,例如
'INITIALLY DEFERRED'
。object_id_name (str) – 对象 ID 访问器的名称。
lazy_load (bool) – 在访问外键字段属性时获取相关对象(如果尚未加载)。如果禁用此选项,访问外键字段将返回存储在外键列中的值。
constraint_name (str) – (可选)用于外键约束的名称。
用于存储外键的字段类。
class User(Model): name = TextField() class Tweet(Model): user = ForeignKeyField(User, backref='tweets') content = TextField() # "user" attribute >>> some_tweet.user <User: charlie> # "tweets" backref attribute >>> for tweet in charlie.tweets: ... print(tweet.content) Some tweet Another tweet Yet another tweet
有关外键、联接和模型之间关系的深入讨论,请参阅 关系和联接。
注意
外键没有特定的
field_type
,因为它们将根据其相关模型上的主键类型获取其字段类型。注意
如果手动指定
field
,该字段必须是主键或具有唯一约束。注意
注意 SQLite 中的外键。默认情况下,ON DELETE 没有任何效果,这可能会对您的数据库完整性产生意外(通常是不可取的)影响。即使您没有指定
on_delete
,这也会影响您,因为默认的 ON DELETE 行为(在不修改数据的情况下失败)不会发生,并且您的数据可能会被静默地重新链接。最安全的方法是在实例化SqliteDatabase
时指定pragmas={'foreign_keys': 1}
。
- class DeferredForeignKey(rel_model_name[, **kwargs])
- 参数
rel_model_name (str) – 要引用的模型名称。
用于表示延迟外键的字段类。对于循环外键引用很有用,例如
class Husband(Model): name = TextField() wife = DeferredForeignKey('Wife', deferrable='INITIALLY DEFERRED') class Wife(Model): name = TextField() husband = ForeignKeyField(Husband, deferrable='INITIALLY DEFERRED')
在上面的示例中,当声明
Wife
模型时,外键Husband.wife
会自动解析并转换为常规的ForeignKeyField
。警告
DeferredForeignKey
引用在声明和创建模型类时解析。这意味着如果您声明一个指向已导入和创建的模型类的DeferredForeignKey
,则延迟外键实例将永远不会解析。例如class User(Model): username = TextField() class Tweet(Model): # This will never actually be resolved, because the User # model has already been declared. user = DeferredForeignKey('user', backref='tweets') content = TextField()
在这些情况下,您应该使用常规的
ForeignKeyField
,或者您可以手动解析延迟外键,如下所示# Tweet.user will be resolved into a ForeignKeyField: DeferredForeignKey.resolve(User)
- class ManyToManyField(model[, backref=None[, through_model=None[, on_delete=None[, on_update=None]]]])
- 参数
ManyToManyField
提供了一个简单的界面,用于处理多对多关系,灵感来自 Django。多对多关系通常通过创建一个连接表来实现,该连接表包含指向两个相关模型的外键。例如,如果您正在为大学生构建一个课程管理系统,那么学生和课程之间的关系将是多对多的。以下是使用标准 API 的模式注意
这不是一个字段,因为没有与之关联的列。相反,它提供了一个方便的界面,用于访问通过中间模型相关的行数据。
声明多对多关系的标准方法(不使用
ManyToManyField
)class Student(Model): name = CharField() class Course(Model): name = CharField() class StudentCourse(Model): student = ForeignKeyField(Student) course = ForeignKeyField(Course)
要查询特定学生的课程,您需要通过连接表进行联接
# List the courses that "Huey" is enrolled in: courses = (Course .select() .join(StudentCourse) .join(Student) .where(Student.name == 'Huey')) for course in courses: print(course.name)
ManyToManyField
旨在通过为连接表中的数据查询和修改提供一个类似字段的 API 来简化此用例。以下是使用ManyToManyField
的代码class Student(Model): name = CharField() class Course(Model): name = CharField() students = ManyToManyField(Student, backref='courses')
注意
从 Peewee 的角度来看,
ManyToManyField
在哪个模型上并不重要,因为反向引用只是镜像。但是,为了编写有效的 Python 代码,您需要在第二个模型上添加ManyToManyField
,以便第一个模型的名称在范围内。我们仍然需要一个连接表来存储学生和课程之间的关系。可以通过调用
get_through_model()
方法访问此模型。这在创建表时很有用。# Create tables for the students, courses, and relationships between # the two. db.create_tables([ Student, Course, Course.students.get_through_model()])
当从模型实例访问时,
ManyToManyField
公开了一个ModelSelect
,表示相关对象的集合。让我们使用交互式 shell 来看看这一切是如何工作的>>> huey = Student.get(Student.name == 'huey') >>> [course.name for course in huey.courses] ['English 101', 'CS 101'] >>> engl_101 = Course.get(Course.name == 'English 101') >>> [student.name for student in engl_101.students] ['Huey', 'Mickey', 'Zaizee']
要添加对象之间的新关系,您可以直接将对象分配给
ManyToManyField
属性,或者调用add()
方法。两者之间的区别在于,简单地分配将清除所有现有关系,而add()
可以保留现有关系。>>> huey.courses = Course.select().where(Course.name.contains('english')) >>> for course in huey.courses.order_by(Course.name): ... print(course.name) English 101 English 151 English 201 English 221 >>> cs_101 = Course.get(Course.name == 'CS 101') >>> cs_151 = Course.get(Course.name == 'CS 151') >>> huey.courses.add([cs_101, cs_151]) >>> [course.name for course in huey.courses.order_by(Course.name)] ['CS 101', 'CS151', 'English 101', 'English 151', 'English 201', 'English 221']
这相当多的课程,所以让我们删除 200 级英语课程。要删除对象,请使用
remove()
方法。>>> huey.courses.remove(Course.select().where(Course.name.contains('2')) 2 >>> [course.name for course in huey.courses.order_by(Course.name)] ['CS 101', 'CS151', 'English 101', 'English 151']
要从集合中删除所有关系,可以使用
clear()
方法。假设英语 101 被取消,因此我们需要从其中删除所有学生>>> engl_101 = Course.get(Course.name == 'English 101') >>> engl_101.students.clear()
注意
有关使用标准 Peewee API 实现多对多关系的概述,请查看 实现多对多 部分。对于除最简单的用例之外的所有情况,最好使用标准 API 实现多对多关系。
- add(value[, clear_existing=True])
- 参数
value – 可以是
Model
实例、模型实例列表或SelectQuery
。clear_existing (bool) – 是否删除现有关系。
将
value
与当前实例关联。您可以传入单个模型实例、模型实例列表,甚至ModelSelect
。示例代码
# Huey needs to enroll in a bunch of courses, including all # the English classes, and a couple Comp-Sci classes. huey = Student.get(Student.name == 'Huey') # We can add all the objects represented by a query. english_courses = Course.select().where( Course.name.contains('english')) huey.courses.add(english_courses) # We can also add lists of individual objects. cs101 = Course.get(Course.name == 'CS 101') cs151 = Course.get(Course.name == 'CS 151') huey.courses.add([cs101, cs151])
- remove(value)
- 参数
value – 可以是
Model
实例、模型实例列表或ModelSelect
。
将
value
与当前实例解除关联。与add()
一样,您可以传入模型实例、模型实例列表,甚至ModelSelect
。示例代码
# Huey is currently enrolled in a lot of english classes # as well as some Comp-Sci. He is changing majors, so we # will remove all his courses. english_courses = Course.select().where( Course.name.contains('english')) huey.courses.remove(english_courses) # Remove the two Comp-Sci classes Huey is enrolled in. cs101 = Course.get(Course.name == 'CS 101') cs151 = Course.get(Course.name == 'CS 151') huey.courses.remove([cs101, cs151])
- clear()
删除所有关联的对象。
示例代码
# English 101 is canceled this semester, so remove all # the enrollments. english_101 = Course.get(Course.name == 'English 101') english_101.students.clear()
- get_through_model()
返回表示多对多连接表的
Model
。这可以在使用through_model
参数实例化字段时手动指定。如果未指定through_model
,则会自动创建一个。在为使用
ManyToManyField
的应用程序创建表时,必须显式创建中间表。# Get a reference to the automatically-created through table. StudentCourseThrough = Course.students.get_through_model() # Create tables for our two models as well as the through model. db.create_tables([ Student, Course, StudentCourseThrough])
- class DeferredThroughModel
在由于依赖关系而无法在不引入 NameErrors 的情况下声明模型或多对多字段的情况下,用于中间模型的占位符。
示例
class Note(BaseModel): content = TextField() NoteThroughDeferred = DeferredThroughModel() class User(BaseModel): username = TextField() notes = ManyToManyField(Note, through_model=NoteThroughDeferred) # Cannot declare this before "User" since it has a foreign-key to # the User model. class NoteThrough(BaseModel): note = ForeignKeyField(Note) user = ForeignKeyField(User) # Resolve dependencies. NoteThroughDeferred.set_model(NoteThrough)
- class CompositeKey(*field_names)
- 参数
field_names – 构成主键的字段名称。
由多个列组成的主键。与其他字段不同,复合主键是在模型的
Meta
类中定义的,在定义字段之后。它将字段的字符串名称作为参数,以用作主键。class BlogTagThrough(Model): blog = ForeignKeyField(Blog, backref='tags') tag = ForeignKeyField(Tag, backref='blogs') class Meta: primary_key = CompositeKey('blog', 'tag')
Schema Manager
- class SchemaManager(model[, database=None[, **context_options]])
-
提供用于管理给定模型的表和索引的创建和删除的方法。
- create_table([safe=True[, **options]])
- 参数
safe (bool) – 指定 IF NOT EXISTS 子句。
options – 任意选项。
为给定模型执行 CREATE TABLE 查询。
- drop_table([safe=True[, drop_sequences=True[, **options]]])
- 参数
safe (bool) – 指定 IF EXISTS 子句。
drop_sequences (bool) – 删除与表上的列关联的任何序列(仅限 postgres)。
options – 任意选项。
为给定模型执行 DROP TABLE 查询。
- truncate_table([restart_identity=False[, cascade=False]])
- 参数
restart_identity (bool) – 重新启动 id 序列(仅限 postgres)。
cascade (bool) – 也截断相关表(仅限 postgres)。
为给定模型执行 TRUNCATE TABLE。如果数据库是 Sqlite,它不支持 TRUNCATE,则将执行等效的 DELETE 查询。
- create_indexes([safe=True])
- 参数
safe (bool) – 指定 IF NOT EXISTS 子句。
为模型定义的索引执行 CREATE INDEX 查询。
- drop_indexes([safe=True])
- 参数
safe (bool) – 指定 IF EXISTS 子句。
为模型定义的索引执行 DROP INDEX 查询。
- create_foreign_key(field)
- 参数
field (ForeignKeyField) – 要添加的外键字段约束。
为给定字段添加外键约束。在大多数情况下,此方法不应是必需的,因为外键约束是在表创建过程中创建的。例外情况是当您使用
DeferredForeignKey
创建循环外键关系时。在这种情况下,有必要先创建表,然后添加延迟外键的约束。class Language(Model): name = TextField() selected_snippet = DeferredForeignKey('Snippet') class Snippet(Model): code = TextField() language = ForeignKeyField(Language, backref='snippets') # Creates both tables but does not create the constraint for the # Language.selected_snippet foreign key (because of the circular # dependency). db.create_tables([Language, Snippet]) # Explicitly create the constraint: Language._schema.create_foreign_key(Language.selected_snippet)
有关更多信息,请参阅有关 循环外键依赖关系 的文档。
警告
由于 SQLite 对修改现有表的支持有限,因此无法将外键约束添加到现有的 SQLite 表中。
- create_all([safe=True[, **table_options]])
- 参数
safe (bool) – 是否指定 IF NOT EXISTS。
为模型创建序列、索引和表。
- drop_all([safe=True[, drop_sequences=True[, **options]]])
- 参数
safe (bool) – 是否指定 IF EXISTS。
drop_sequences (bool) – 删除与表上的列关联的任何序列(仅限 postgres)。
options – 任意选项。
删除模型的表和关联的索引。
Model
- class Metadata(model[, database=None[, table_name=None[, indexes=None[, primary_key=None[, constraints=None[, schema=None[, only_save_dirty=False[, depends_on=None[, options=None[, without_rowid=False[, strict_tables=False[, **kwargs]]]]]]]]]]]]])
- 参数
model (Model) – 模型类。
database (Database) – 模型绑定的数据库。
table_name (str) – 指定模型的表名。
indexes (list) –
ModelIndex
对象列表。primary_key – 模型的主键(仅在它是
CompositeKey
或False
表示没有主键时指定)。constraints (list) – 表约束列表。
schema (str) – 表所在的模式。
only_save_dirty (bool) – 当调用
save()
时,仅保存已修改的字段。options (dict) – 模型的任意选项。
without_rowid (bool) – 指定 WITHOUT ROWID(仅限 sqlite)。
strict_tables (bool) – 指定 STRICT(仅限 sqlite,需要 3.37+)。
kwargs – 任意设置属性和值。
存储
Model
的元数据。此类不应直接实例化,而是使用
Model
类内部的Meta
类的属性实例化。元数据属性随后可在Model._meta
上使用。- model_graph([refs=True[, backrefs=True[, depth_first=True]]])
- 参数
refs (bool) – 跟踪外键引用。
backrefs (bool) – 跟踪外键反向引用。
depth_first (bool) – 进行深度优先搜索(
False
表示广度优先)。
遍历模型图并返回一个包含 3 元组的列表,每个元组包含
(foreign key field, model class, is_backref)
。
- set_table_name(table_name)
- 参数
table_name (str) – 要绑定模型的表名。
在运行时将模型类绑定到给定的表名。
- class SubclassAwareMetadata
跟踪
Model
子类的元数据子类。当您需要跟踪项目中的所有模型时很有用。示例
from peewee import SubclassAwareMetadata class Base(Model): class Meta: database = db model_metadata_class = SubclassAwareMetadata # Create 3 model classes that inherit from Base. class A(Base): pass class B(Base): pass class C(Base): pass # Now let's make a helper for changing the `schema` for each Model. def change_schema(schema): def _update(model): model._meta.schema = schema return _update # Set all models to use "schema1", e.g. "schema1.a", "schema1.b", etc. # Will apply the function to every subclass of Base. Base._meta.map_models(change_schema('schema1')) # Set all models to use "schema2", e.g. "schema2.a", "schema2.b", etc. Base._meta.map_models(change_schema('schema2'))
- map_models(fn)
将函数应用于所有子类。
- class Model(**kwargs)
- 参数
kwargs – 字段名到值的映射,用于初始化模型。
Model 类为使用数据库表提供了一个高级抽象。模型与数据库表(或类似表的对象,例如视图)之间是一对一映射。
Model
的子类声明任意数量的Field
实例作为类属性。这些字段对应于表上的列。表级操作,例如
select()
、update()
、insert()
和delete()
作为类方法实现。行级操作,例如save()
和delete_instance()
作为实例方法实现。示例
db = SqliteDatabase(':memory:') class User(Model): username = TextField() join_date = DateTimeField(default=datetime.datetime.now) is_admin = BooleanField(default=False) admin = User(username='admin', is_admin=True) admin.save()
- classmethod alias([alias=None])
- 参数
alias (str) – 别名的可选名称。
- 返回值
ModelAlias
实例。
创建模型类的别名。模型别名允许您在查询中多次引用同一个
Model
,例如在进行自连接或子查询时。示例
Parent = Category.alias() sq = (Category .select(Category, Parent) .join(Parent, on=(Category.parent == Parent.id)) .where(Parent.name == 'parent category'))
- classmethod select(*fields)
- 参数
fields – 模型类、字段实例、函数或表达式的列表。如果未提供任何参数,则默认情况下将选择给定模型的所有列。除非您将查询用作子查询,在这种情况下,默认情况下仅选择主键。
- 返回值
ModelSelect
查询。
创建 SELECT 查询。如果未明确提供任何字段,则查询默认情况下将 SELECT 模型上定义的所有字段,除非您将查询用作子查询,在这种情况下,默认情况下仅选择主键。
选择所有列的示例
query = User.select().where(User.active == True).order_by(User.username)
选择 Tweet 上的所有列以及父模型 User 的示例。当在 Tweet 实例上访问
user
外键时,将不需要额外的查询(有关更多详细信息,请参阅 N+1)query = (Tweet .select(Tweet, User) .join(User) .order_by(Tweet.created_date.desc())) for tweet in query: print(tweet.user.username, '->', tweet.content)
仅选择主键的子查询示例
inactive_users = User.select().where(User.active == False) # Here, instead of defaulting to all columns, Peewee will default # to only selecting the primary key. Tweet.delete().where(Tweet.user.in_(inactive_users)).execute()
- classmethod update([__data=None[, **update]])
- 参数
__data (dict) – 要更新的字段到值的
dict
。update – 字段名到值的映射。
创建 UPDATE 查询。
显示如果用户的注册已过期,则将其标记为非活动用户的示例
q = (User .update({User.active: False}) .where(User.registration_expired == True)) q.execute() # Execute the query, returning number of rows updated.
显示原子更新的示例
q = (PageView .update({PageView.count: PageView.count + 1}) .where(PageView.url == url)) q.execute() # Execute the query.
注意
执行更新查询时,将返回修改的行数。
- classmethod insert([__data=None[, **insert]])
- 参数
__data (dict) – 要插入的字段到值的
dict
。insert – 字段名到值的映射。
创建 INSERT 查询。
将新行插入数据库。如果模型上的任何字段具有默认值,则如果在
insert
字典中未明确设置这些字段,则将使用这些值。显示创建新用户的示例
q = User.insert(username='admin', active=True, registration_expired=False) q.execute() # perform the insert.
您也可以使用
Field
对象作为键new_id = User.insert({User.username: 'admin'}).execute()
如果您有一个模型,其中一个字段具有默认值,并且该字段未在
insert
参数中指定,则将使用默认值class User(Model): username = CharField() active = BooleanField(default=True) # This INSERT query will automatically specify `active=True`: User.insert(username='charlie')
注意
在具有自动递增主键的表上执行插入查询时,将返回新行的主键。
- classmethod insert_many(rows[, fields=None])
- 参数
rows – 生成要插入的行可迭代对象。
fields (list) – 要插入的字段列表。
- 返回值
修改的行数(见注释)。
插入多行数据。
rows
参数必须是生成字典或元组的可迭代对象,其中元组值的顺序对应于fields
参数中指定的字段。与insert()
一样,字典中未指定的字段将使用其默认值(如果存在)。注意
由于批量插入的性质,每行必须包含相同的字段。以下将不起作用
Person.insert_many([ {'first_name': 'Peewee', 'last_name': 'Herman'}, {'first_name': 'Huey'}, # Missing "last_name"! ]).execute()
插入多个用户的示例
data = [ ('charlie', True), ('huey', False), ('zaizee', False)] query = User.insert_many(data, fields=[User.username, User.is_admin]) query.execute()
使用字典的等效示例
data = [ {'username': 'charlie', 'is_admin': True}, {'username': 'huey', 'is_admin': False}, {'username': 'zaizee', 'is_admin': False}] # Insert new rows. User.insert_many(data).execute()
因为
rows
参数可以是任意可迭代对象,所以您也可以使用生成器def get_usernames(): for username in ['charlie', 'huey', 'peewee']: yield {'username': username} User.insert_many(get_usernames()).execute()
警告
如果您使用的是 SQLite,则您的 SQLite 库必须是 3.7.11 或更高版本才能利用批量插入。
注意
SQLite 每个语句默认限制了绑定变量的数量。这个限制可以在编译时或运行时修改,**但是**如果在运行时修改,你只能指定比默认限制更低的数值。
更多信息,请查看以下 SQLite 文档
注意
默认返回值是修改的行数。但是,当使用 Postgres 时,Peewee 默认会返回一个游标,它会生成插入行的主键。要禁用 Postgres 中的此功能,请使用
as_rowcount()
。
- classmethod insert_from(query, fields)
- 参数
query (Select) – 用作数据来源的 SELECT 查询。
fields – 要插入数据的字段。
- 返回值
修改的行数(见注释)。
使用 SELECT 查询作为源插入数据。此 API 应用于形式为 INSERT INTO … SELECT FROM … 的查询。
跨表插入数据的示例,用于反规范化目的
source = (User .select(User.username, fn.COUNT(Tweet.id)) .join(Tweet, JOIN.LEFT_OUTER) .group_by(User.username)) UserTweetDenorm.insert_from( source, [UserTweetDenorm.username, UserTweetDenorm.num_tweets]).execute()
注意
默认返回值是修改的行数。但是,当使用 Postgres 时,Peewee 默认会返回一个游标,它会生成插入行的主键。要禁用 Postgres 中的此功能,请使用
as_rowcount()
。
- classmethod replace([__data=None[, **insert]])
- 参数
__data (dict) – 要插入的字段到值的
dict
。insert – 字段名到值的映射。
创建一个 INSERT 查询,使用 REPLACE 进行冲突解决。
有关示例,请参见
Model.insert()
。
- classmethod replace_many(rows[, fields=None])
- 参数
rows – 生成要插入的行可迭代对象。
fields (list) – 要插入的字段列表。
使用 REPLACE 进行冲突解决,插入多行数据。
有关示例,请参见
Model.insert_many()
。
- classmethod raw(sql, *params)
- 参数
sql (str) – 要执行的 SQL 查询。
params – 查询参数。
直接执行 SQL 查询。
从 User 表中选择行的示例
q = User.raw('select id, username from users') for user in q: print(user.id, user.username)
注意
通常,
raw
的使用保留用于可以显着优化选择查询的那些情况。它对选择查询很有用,因为它将返回模型的实例。
- classmethod delete()
创建一个 DELETE 查询。
显示删除所有非活动用户的示例
q = User.delete().where(User.active == False) q.execute() # Remove the rows, return number of rows removed.
警告
此方法对整个表执行删除操作。要删除单个实例,请参见
Model.delete_instance()
。
- classmethod create(**query)
- 参数
query – 字段名到值的映射。
将新行插入表中并返回相应的模型实例。
显示创建用户的示例(将向数据库添加一行)
user = User.create(username='admin', password='test')
注意
create() 方法是实例化然后保存的简写。
- classmethod bulk_create(model_list[, batch_size=None])
- 参数
model_list (iterable) – 未保存的
Model
实例的列表或其他可迭代对象。batch_size (int) – 每次插入要批处理的行数。如果未指定,所有模型都将在单个查询中插入。
- 返回值
没有返回值。
有效地将多个未保存的模型实例插入数据库。与
insert_many()
不同,该方法接受行数据作为字典或列表的列表,此方法接受未保存的模型实例的列表。示例
# List of 10 unsaved users. user_list = [User(username='u%s' % i) for i in range(10)] # All 10 users are inserted in a single query. User.bulk_create(user_list)
批次
user_list = [User(username='u%s' % i) for i in range(10)] with database.atomic(): # Will execute 4 INSERT queries (3 batches of 3, 1 batch of 1). User.bulk_create(user_list, batch_size=3)
警告
新创建模型的主键值仅在使用 Postgresql(支持
RETURNING
子句)时才会设置。SQLite 通常对查询的绑定参数有限制,因此最大批次大小应为参数限制 / 字段数量。此限制通常对于 Sqlite < 3.32.0 为 999,对于较新版本为 32766。
当提供批次大小时,**强烈建议**您使用
Database.atomic()
将调用包装在事务或保存点中。否则,批次中间的错误可能会导致数据库处于不一致状态。
- classmethod bulk_update(model_list, fields[, batch_size=None])
- 参数
model_list (iterable) –
Model
实例的列表或其他可迭代对象。fields (list) – 要更新的字段列表。
batch_size (int) – 每次插入要批处理的行数。如果未指定,所有模型都将在单个查询中插入。
- 返回值
更新的行总数。
有效地更新多个模型实例。
示例
# First, create 3 users. u1, u2, u3 = [User.create(username='u%s' % i) for i in (1, 2, 3)] # Now let's modify their usernames. u1.username = 'u1-x' u2.username = 'u2-y' u3.username = 'u3-z' # Update all three rows using a single UPDATE query. User.bulk_update([u1, u2, u3], fields=[User.username])
这将导致执行以下 SQL
UPDATE "users" SET "username" = CASE "users"."id" WHEN 1 THEN "u1-x" WHEN 2 THEN "u2-y" WHEN 3 THEN "u3-z" END WHERE "users"."id" IN (1, 2, 3);
如果您有大量对象要更新,强烈建议您指定
batch_size
并将操作包装在事务中with database.atomic(): User.bulk_update(user_list, fields=['username'], batch_size=50)
警告
SQLite 通常对查询的绑定参数有限制。此限制通常对于 Sqlite < 3.32.0 为 999,对于较新版本为 32766。
当提供批次大小时,**强烈建议**您使用
Database.atomic()
将调用包装在事务或保存点中。否则,批次中间的错误可能会导致数据库处于不一致状态。
- classmethod get(*query, **filters)
- 参数
query – 零个或多个
Expression
对象。filters – 字段名到值的映射,用于 Django 风格的过滤器。
- 引发
DoesNotExist
- 返回值
与指定过滤器匹配的模型实例。
检索与给定过滤器匹配的单个模型实例。如果未返回模型,则会引发
DoesNotExist
。user = User.get(User.username == username, User.active == True)
此方法也通过
SelectQuery
公开,尽管它不接受任何参数active = User.select().where(User.active == True) try: user = active.where( (User.username == username) & (User.active == True) ).get() except User.DoesNotExist: user = None
注意
get()
方法是使用限制为 1 的选择操作的简写。它具有在未找到匹配行时引发异常的附加行为。如果找到多行,则将使用数据库游标返回的第一行。
- classmethod get_or_none(*query, **filters)
与
Model.get()
相同,但如果没有任何模型与给定过滤器匹配,则返回None
。
- classmethod get_by_id(pk)
- 参数
pk – 主键值。
调用
Model.get()
的简写,指定按主键查找。如果不存在具有给定主键值的实例,则会引发DoesNotExist
。示例
user = User.get_by_id(1) # Returns user with id = 1.
- classmethod set_by_id(key, value)
- 参数
key – 主键值。
value (dict) – 要更新的字段到值的映射。
使用给定主键更新数据的简写。如果不存在具有给定主键的行,则不会引发异常。
示例
# Set "is_admin" to True on user with id=3. User.set_by_id(3, {'is_admin': True})
- classmethod delete_by_id(pk)
- 参数
pk – 主键值。
删除具有给定主键的行的简写。如果不存在具有给定主键的行,则不会引发异常。
- classmethod get_or_create(**kwargs)
- 参数
kwargs – 字段名到值的映射。
defaults – 创建新行时使用的默认值。
- 返回值
包含
Model
实例和布尔值的元组,指示是否创建了新对象。
尝试获取与给定过滤器匹配的行。如果找不到匹配的行,则创建一个新行。
警告
使用此方法时可能会出现竞争条件。
不使用
get_or_create
的示例# Without `get_or_create`, we might write: try: person = Person.get( (Person.first_name == 'John') & (Person.last_name == 'Lennon')) except Person.DoesNotExist: person = Person.create( first_name='John', last_name='Lennon', birthday=datetime.date(1940, 10, 9))
使用
get_or_create
的等效代码person, created = Person.get_or_create( first_name='John', last_name='Lennon', defaults={'birthday': datetime.date(1940, 10, 9)})
- classmethod filter(*dq_nodes, **filters)
- 参数
dq_nodes – 零个或多个
DQ
对象。filters – Django 风格的过滤器。
- 返回值
ModelSelect
查询。
- get_id()
- 返回值
模型实例的主键。
- save([force_insert=False[, only=None]])
- 参数
force_insert (bool) – 强制 INSERT 查询。
only (list) – 只保存给定的
Field
实例。
- 返回值
修改的行数。
保存模型实例中的数据。默认情况下,主键值的存在会导致执行 UPDATE 查询。
显示保存模型实例的示例
user = User() user.username = 'some-user' # does not touch the database user.save() # change is persisted to the db
- dirty_fields
返回已修改的字段列表。
- 返回类型
list
注意
如果您只想持久化修改的字段,可以调用
model.save(only=model.dirty_fields)
。如果您始终只想保存模型的脏字段,可以使用 Meta 选项
only_save_dirty = True
。然后,每次调用Model.save()
时,默认情况下只会保存脏字段,例如class Person(Model): first_name = CharField() last_name = CharField() dob = DateField() class Meta: database = db only_save_dirty = True
警告
Peewee 通过观察何时在模型实例上设置字段属性来确定字段是否为“脏”。如果字段包含可变的值,例如字典实例,并且该字典随后被修改,Peewee 将不会注意到更改。
- is_dirty()
返回布尔值,指示是否手动设置了任何字段。
- delete_instance([recursive=False[, delete_nullable=False]])
- 参数
recursive (bool) – 删除相关模型。
delete_nullable (bool) – 删除具有空外键的相关模型。如果为
False
,则可空关系将被设置为 NULL。
删除给定的实例。任何设置为级联删除的外键将自动删除。为了获得更具程序性的控制,您可以指定
recursive=True
,这将删除任何不可空的相关模型(那些是可空的将被设置为 NULL)。如果您希望删除所有依赖项,无论它们是否可空,请设置delete_nullable=True
。示例
some_obj.delete_instance() # it is gone forever
- classmethod bind(database[, bind_refs=True[, bind_backrefs=True]])
- 参数
database (Database) – 要绑定的数据库。
bind_refs (bool) – 绑定相关模型。
bind_backrefs (bool) – 绑定反向引用相关模型。
将模型(和指定的关联)绑定到给定的数据库。
另请参阅:
Database.bind()
。
- classmethod bind_ctx(database[, bind_refs=True[, bind_backrefs=True]])
与
bind()
相似,但返回一个上下文管理器,它只在包装块的持续时间内绑定模型。另请参阅:
Database.bind_ctx()
。
- classmethod table_exists()
- 返回值
指示表是否存在布尔值。
- classmethod create_table([safe=True[, **options]])
- 参数
safe (bool) – 如果设置为
True
,则创建表查询将包含IF NOT EXISTS
子句。
创建模型表、索引、约束和序列。
示例
with database: SomeModel.create_table() # Execute the create table query.
- classmethod drop_table([safe=True[, **options]])
- 参数
safe (bool) – 如果设置为
True
,则创建表查询将包含IF EXISTS
子句。
删除模型表。
- truncate_table([restart_identity=False[, cascade=False]])
- 参数
restart_identity (bool) – 重新启动 id 序列(仅限 postgres)。
cascade (bool) – 也截断相关表(仅限 postgres)。
截断(删除所有行)模型。
- classmethod index(*fields[, unique=False[, safe=True[, where=None[, using=None[, name=None]]]]])
- 参数
fields – 要索引的字段。
unique (bool) – 索引是否为 UNIQUE。
safe (bool) – 是否添加 IF NOT EXISTS 子句。
where (Expression) – 索引的可选 WHERE 子句。
using (str) – 索引算法。
name (str) – 可选的索引名称。
用于在模型上声明索引的表达方式。包装
ModelIndex
实例的声明。示例
class Article(Model): name = TextField() timestamp = TimestampField() status = IntegerField() flags = BitField() is_sticky = flags.flag(1) is_favorite = flags.flag(2) # CREATE INDEX ... ON "article" ("name", "timestamp" DESC) idx = Article.index(Article.name, Article.timestamp.desc()) # Be sure to add the index to the model: Article.add_index(idx) # CREATE UNIQUE INDEX ... ON "article" ("timestamp" DESC, "flags" & 2) # WHERE ("status" = 1) idx = (Article .index(Article.timestamp.desc(), Article.flags.bin_and(2), unique=True) .where(Article.status == 1)) # Add index to model: Article.add_index(idx)
- classmethod add_index(*args, **kwargs)
- 参数
args –
ModelIndex
实例、要索引的字段或包含用于创建索引的 SQL 的SQL
实例。kwargs – 传递给
ModelIndex
构造函数的关键字参数。
将索引添加到模型的定义中。
注意
此方法实际上不会在数据库中创建索引。相反,它将索引定义添加到模型的元数据中,以便后续对
create_table()
的调用将创建新索引(以及表)。示例
class Article(Model): name = TextField() timestamp = TimestampField() status = IntegerField() flags = BitField() is_sticky = flags.flag(1) is_favorite = flags.flag(2) # CREATE INDEX ... ON "article" ("name", "timestamp") WHERE "status" = 1 idx = Article.index(Article.name, Article.timestamp).where(Article.status == 1) Article.add_index(idx) # CREATE UNIQUE INDEX ... ON "article" ("timestamp" DESC, "flags" & 2) ts_flags_idx = Article.index( Article.timestamp.desc(), Article.flags.bin_and(2), unique=True) Article.add_index(ts_flags_idx) # You can also specify a list of fields and use the same keyword # arguments that the ModelIndex constructor accepts: Article.add_index( Article.name, Article.timestamp.desc(), where=(Article.status == 1)) # Or even specify a SQL query directly: Article.add_index(SQL('CREATE INDEX ...'))
- dependencies([search_nullable=False])
- 参数
search_nullable (bool) – 搜索通过可空外键关联的模型
- 返回类型
生成器表达式,生成查询和外键字段。
生成依赖模型的查询列表。生成包含查询和对应外键字段的 2 元组。用于搜索模型的依赖项,例如在删除事件中将成为孤儿的内容。
- __iter__()
- 返回值
给定类的
ModelSelect
。
用于迭代模型所有实例的便捷函数。
示例
Setting.insert_many([ {'key': 'host', 'value': '192.168.1.2'}, {'key': 'port': 'value': '1337'}, {'key': 'user': 'value': 'nuggie'}]).execute() # Load settings from db into dict. settings = {setting.key: setting.value for setting in Setting}
- __len__()
- 返回值
表中行的数量。
示例
n_accounts = len(Account) # Is equivalent to: n_accounts = Account.select().count()
- class ModelAlias(model[, alias=None])
- 参数
model (Model) – 要引用的模型类。
alias (str) – (可选) 别名的名称。
在查询中提供对模型的单独引用。
- class ModelSelect(model, fields_or_models)
- 参数
model (Model) – 要选择的模型类。
fields_or_models – 要选择的字段或模型类的列表。
模型特定的 SELECT 查询实现。
- switch([ctx=None])
- 参数
ctx –
Model
、ModelAlias
、子查询或其他已连接的对象。
切换连接上下文 - 后续对
join()
的调用将针对其进行连接。用于指定针对单个表的多个连接。如果未提供
ctx
,则将使用查询的模型。以下示例从 tweet 中选择并连接到 user 和 tweet-flag
sq = Tweet.select().join(User).switch(Tweet).join(TweetFlag) # Equivalent (since Tweet is the query's model) sq = Tweet.select().join(User).switch().join(TweetFlag)
- objects([constructor=None])
- 参数
constructor – 构造函数(默认为返回模型实例)
使用给定的构造函数返回结果行作为创建的对象。默认行为是创建模型实例。
注意
此方法可用于从多个源/模型中选择字段数据时,将所有数据作为属性提供给正在查询的模型(而不是构建已连接模型实例的图)。对于非常复杂的查询,这可能会对性能产生积极影响,尤其是在迭代大型结果集时。
类似地,您可以使用
dicts()
、tuples()
或namedtuples()
来获得更高的性能。
- join(dest[, join_type='INNER'[, on=None[, src=None[, attr=None]]]])
- 参数
dest –
Model
、ModelAlias
、Select
查询或其他要连接的对象。join_type (str) – 连接类型,默认为 INNER。
on – 连接谓词或要连接的
ForeignKeyField
。src – 显式指定连接的源。如果未指定,则将使用当前连接上下文。
attr (str) – 从已连接模型中投影列时要使用的属性。
与另一个表状对象连接。
联接类型可以是以下之一
JOIN.INNER
JOIN.LEFT_OUTER
JOIN.RIGHT_OUTER
JOIN.FULL
JOIN.FULL_OUTER
JOIN.CROSS
示例选择 tweet 并连接到 user 以限制为仅由“admin”用户发出的 tweet
sq = Tweet.select().join(User).where(User.is_admin == True)
示例选择用户并连接到特定外键字段。有关实际使用情况,请参阅 示例应用程序
sq = User.select().join(Relationship, on=Relationship.to_user)
有关外键、联接和模型之间关系的深入讨论,请参阅 关系和联接。
- join_from(src, dest[, join_type='INNER'[, on=None[, attr=None]]])
- 参数
src – 连接的源。
dest – 要连接的表。
使用与非模型特定
join()
相同的参数顺序。通过要求指定连接源来绕过连接上下文。
- filter(*args, **kwargs)
- 参数
args – 零个或多个
DQ
对象。kwargs – Django 风格的关键字参数过滤器。
使用 Django 风格的过滤器来表达 WHERE 子句。连接后可以链接外键字段。支持的操作有
eq
- 等于ne
- 不等于lt
,lte
- 小于,小于或等于gt
,gte
- 大于,大于或等于in
- 在值集中is
- IS(例如 IS NULL)。like
,ilike
- LIKE 和 ILIKE(不区分大小写)regexp
- 正则表达式匹配
示例
# Get all tweets by user with username="peewee". q = Tweet.filter(user__username='peewee') # Get all posts that are draft or published, and written after 2023. q = Post.filter( (DQ(status='draft') | DQ(status='published')), timestamp__gte=datetime.date(2023, 1, 1))
- prefetch(*subqueries[, prefetch_type=PREFETCH_TYPE.WHERE])
- 参数
subqueries – 要预取的
Model
类或选择查询列表。prefetch_type – 用于子查询的查询类型。
- 返回值
包含预取关系的模型列表。
执行查询,预取给定的额外资源。
预取类型可以是以下之一
PREFETCH_TYPE.WHERE
PREFETCH_TYPE.JOIN
另请参阅
prefetch()
独立函数。示例
# Fetch all Users and prefetch their associated tweets. query = User.select().prefetch(Tweet) for user in query: print(user.username) for tweet in user.tweets: print(' *', tweet.content)
注意
由于
prefetch
必须重建模型图,因此必须确保任何相关模型的外键/主键都被选中,以便正确映射相关对象。
- prefetch(sq, *subqueries[, prefetch_type=PREFETCH_TYPE.WHERE])
- 参数
sq – 用作起点的查询。
subqueries – 要急切获取的一个或多个模型或
ModelSelect
查询。prefetch_type – 用于子查询的查询类型。
- 返回值
包含预取关系的模型列表。
急切获取相关对象,允许在存在一对多关系时有效地查询多个表。预取类型会改变子查询的构建方式,这在使用不同的数据库引擎时可能需要。
预取类型可以是以下之一
PREFETCH_TYPE.WHERE
PREFETCH_TYPE.JOIN
例如,有效地查询多对一关系很简单
query = (Tweet .select(Tweet, User) .join(User)) for tweet in query: # Looking up tweet.user.username does not require a query since # the related user's columns were selected. print(tweet.user.username, '->', tweet.content)
为了有效地进行反向操作,查询用户及其推文,可以使用 prefetch
query = User.select() for user in prefetch(query, Tweet): print(user.username) for tweet in user.tweets: # Does not require additional query. print(' ', tweet.content)
注意
由于
prefetch
必须重建模型图,因此必须确保任何相关模型的外键/主键都被选中,以便正确映射相关对象。
查询构建器内部
- class AliasManager
管理分配给
Source
对象的别名,以避免在单个查询中使用多个源时出现不明确的引用。- add(source)
将源添加到 AliasManager 的内部注册表中的当前范围。别名将使用以下方案自动生成(其中每个缩进级别表示一个新范围)
- 参数
source (Source) – 使管理器了解新的源。如果源已添加,则调用将是无操作。
- get(source[, any_depth=False])
返回当前范围中源的别名。如果源没有别名,它将被赋予下一个可用的别名。
- 参数
source (Source) – 应该检索其别名的源。
- 返回值
已分配给源的别名,或下一个可用的别名。
- 返回类型
str
- push()
将新范围推送到堆栈。
- pop()
从堆栈中弹出范围。
- class State(scope[, parentheses=False[, subquery=False[, **kwargs]]])
用于表示给定范围状态的轻量级对象。在 SQL 生成期间,
Context
访问的每个对象都可以检查状态。State
类允许 Peewee 执行以下操作对字段类型或 SQL 表达式使用通用接口,但使用特定于供应商的数据类型或运算符。
根据
scope
的值,将Column
实例编译为完全限定的属性,作为命名别名等。确保括号的使用适当。
- 参数
scope (int) – 状态处于活动状态时要应用的范围规则。
parentheses (bool) – 将包含的 SQL 包含在括号中。
subquery (bool) – 当前状态是否为外部查询的子查询。
kwargs (dict) – 应该在当前状态下应用的任意设置。
- class Context(**settings)
将 Peewee 结构转换为参数化的 SQL 查询。
Peewee 结构都应该实现一个 __sql__ 方法,该方法将在 SQL 生成期间由 Context 类调用。 __sql__ 方法接受一个参数,即 Context 实例,它允许递归下降和范围和状态的内省。
- scope
返回当前活动的范围规则。
- parentheses
返回当前状态是否包含在括号中。
- subquery
返回当前状态是否为另一个查询的子查询。
- scope_normal([**kwargs])
默认范围。源通过别名引用,列通过源的点分路径引用。
- scope_source([**kwargs])
在定义源时使用的范围,例如在 SELECT 查询的列列表和 FROM 子句中。此范围用于定义源的完全限定名称并分配别名。
- scope_values([**kwargs])
用于 UPDATE、INSERT 或 DELETE 查询的范围,其中我们直接引用源,而不是通过别名引用它。类似地,由于只有一个表,因此不需要通过点分路径引用列。
- scope_cte([**kwargs])
在生成公用表表达式的内容时使用的范围。在 WITH 语句之后使用,在生成 CTE 的定义(而不是仅仅引用 CTE)时使用。
- scope_column([**kwargs])
在为列生成 SQL 时使用的范围。确保列以其正确的别名呈现。这是因为在引用子选择内部投影时,Peewee 会将完整的 SELECT 查询呈现为列的“源”(而不是查询的别名 + . + 列)。此范围允许我们在只需要别名时避免呈现完整的查询。
- sql(obj)
将可组合的 Node 对象、子上下文或其他对象追加到查询 AST。Python 值(如整数、字符串、浮点数等)被视为参数化值。
- 返回值
更新的 Context 对象。
- literal(keyword)
将字符串文字追加到当前查询 AST。
- 返回值
更新的 Context 对象。
- parse(node)
- 参数
node (Node) – Node 子类的实例。
- 返回值
由 (sql, parameters) 组成的 2 元组。
将给定节点转换为 SQL AST 并返回由 SQL 查询和参数组成的 2 元组。
- query()
- 返回值
由 (sql, parameters) 组成的 2 元组,用于上下文。
常量和助手
- class Proxy
为另一个对象创建代理或占位符。
- initialize(obj)
- 参数
obj – 要代理的对象。
将代理绑定到给定对象。之后,对代理的所有属性查找和方法调用都将发送到给定对象。
将调用已注册的任何回调。
- attach_callback(callback)
- 参数
callback – 一个接受单个参数(绑定对象)的函数。
- 返回值
self
添加一个回调,在代理初始化时执行。
- chunked(iterable, n)
- 参数
iterable – 一个可迭代对象,它是要分块的数据源。
n (int) – 块大小
- 返回值
一个新的可迭代对象,它生成源数据的 n 长度块。
将大型数据列表分解成更小块的有效实现。
用法
it = range(10) # An iterable that yields 0...9. # Break the iterable into chunks of length 4. for chunk in chunked(it, 4): print(', '.join(str(num) for num in chunk)) # PRINTS: # 0, 1, 2, 3 # 4, 5, 6, 7 # 8, 9