API文档
此文档指定Peewee的API。
数据库
- class Database(database[, thread_safe=True[, field_types=None[, operations=None[, autoconnect=True[, **kwargs]]]]])
- 参数:
database (str) -- sqlite的数据库名称或文件名(或
None
到 defer initialization ,在这种情况下,您必须致电Database.init()
,指定数据库名称)。thread_safe (bool) -- 是否在本地线程中存储连接状态。
field_types (dict) -- 要支持的其他字段类型的映射。
operations (dict) -- 要支持的附加操作的映射。
autoconnect (bool) -- 如果试图对关闭的数据库执行查询,则自动连接到数据库。
kwargs -- 例如,创建连接时将传递给数据库驱动程序的任意关键字参数
password
,host
等。
这个
Database
负责:正在执行查询
管理连接
交易
反省
备注
数据库可以用
None
如果数据库在运行时之前未知,则作为数据库名称。通过这种方式,您可以创建一个数据库实例,然后在已知设置的情况下在其他地方配置它。这叫做 deferred* initialization .实例:
# 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
等。
初始化 deferred 数据库。见 运行时数据库配置 更多信息。
- 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 -- 供内部使用。
返回A
cursor
当前连接上的对象。如果连接未打开,将打开一个连接。光标将是基础数据库驱动程序用来封装数据库光标的任何对象。
- execute_sql(sql[, params=None])
- 参数:
sql (str) -- 要执行的SQL字符串。
params (tuple) -- 用于查询的参数。
- 返回:
游标对象。
执行一个SQL查询并在结果上返回一个光标。
- execute(query[, **context_options])
- 参数:
query -- A
Query
实例。context_options -- 传递给SQL生成器的任意选项。
- 返回:
游标对象。
通过编译
Query
实例并执行生成的SQL。
- last_insert_id(cursor[, query_type=None])
- 参数:
cursor -- 游标对象。
- 返回:
最后插入行的主键。
- rows_affected(cursor)
- 参数:
cursor -- 游标对象。
- 返回:
查询修改的行数。
- in_transaction()
- 返回:
事务当前是否打开。
- 返回类型:
bool
- atomic()
创建一个上下文管理器,在事务中运行包装块中的任何查询(如果块嵌套,则保存点)。
呼叫
atomic()
可以嵌套。atomic()
也可用作装饰。示例代码:
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_commit()
或session_rollback()
在呼叫session_start
方法。
- session_commit()
提交在以开始的事务期间所做的任何更改
session_start()
.
- session_rollback()
回滚在以开始的事务期间所做的任何更改
session_start()
.
- transaction()
创建一个上下文管理器,用于运行事务中包装块中的所有查询。
警告
呼叫
transaction
不能嵌套。只有最重要的电话才能生效。回滚或提交嵌套事务上下文管理器具有未定义的行为。
- savepoint()
创建一个上下文管理器,运行保存点中包装块中的所有查询。保存点可以任意嵌套。
警告
呼叫
savepoint
必须发生在事务内部。
- begin()
使用手动提交模式时启动事务。
备注
此方法只能与
manual_commit()
上下文管理器。
- commit()
手动提交当前活动的事务。
备注
此方法只能与
manual_commit()
上下文管理器。
- rollback()
手动回滚当前活动的事务。
备注
此方法只能与
manual_commit()
上下文管理器。
- batch_commit(it, n)
- 参数:
it (iterable) -- 将生成其项的iterable。
n (int) -- 每一个承诺 n 项目。
- 返回:
与所提供的等价物,加上 n 项目将在事务中生成。
此方法的目的是简化批处理大型操作,如插入、更新等。传入一个iterable和每个批的项数,这些项将由一个等效的迭代器返回,该迭代器将每个批包装在一个事务中。
例子:
# 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) -- 架构名称(可选)。
返回的列表
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) -- 要提取的日期部分,例如“年份”。
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 key和value的2元组列表。
timeout -- 在sqlite驱动程序上设置忙超时(秒)。
returning_clause (bool) -- 使用 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
获取或设置当前连接的缓存大小pragma。
- foreign_keys
获取或设置当前连接的外键pragma。
- journal_mode
获取或设置日志模式pragma。
- journal_size_limit
获取或设置日志大小限制pragma。
- mmap_size
获取或设置当前连接的mmap-size pragma。
- page_size
获取或设置页面大小pragma。
- read_uncommitted
获取或设置当前连接的read_uncommitted pragma。
- 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) -- 排序规则名称(默认为函数名)
decorator注册用户定义的排序规则。
例子:
@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表示任何数字。
deterministic (bool) -- 对于给定的输入,该函数是否具有确定性(这是在索引中使用该函数所必需的)。需要Sqlite 3.20或更高版本,以及
sqlite3
驱动程序支持(添加到Python3.8中的stdlib中)。
注册用户定义的标量函数。每次打开新连接时都会注册该函数。此外,如果连接已打开,则该函数将注册为打开的连接。
- func([name=None[, num_params=-1[, deterministic=None]]])
- 参数:
name (str) -- 函数名(默认为函数名)。
num_params (int) -- 函数接受的参数个数,或-1表示任何数字。
deterministic (bool) -- 对于给定的输入,该函数是否具有确定性(这是在索引中使用该函数所必需的)。需要Sqlite 3.20或更高版本,以及
sqlite3
驱动程序支持(添加到Python3.8中的stdlib中)。
decorator注册用户定义的标量函数。
例子:
@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 and pysqlite3 >0.2.0。
每次打开新连接时都会注册window函数。此外,如果连接已打开,则窗口功能将注册为打开的连接。
- window_function([name=None[, num_params=-1]])
- 参数:
name (str) -- 窗口函数的名称(默认为类名)。
num_params (int) -- 函数接受的参数个数,或-1表示任何数字。
类decorator注册用户定义的窗口函数。窗口函数必须定义以下方法:
step(<params>)
-从行接收值并更新状态。inverse(<params>)
-逆step()
对于给定的值。value()
-返回window函数的当前值。finalize()
-返回window函数的最终值。
例子:
@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 -- 用户定义的表函数的名称。
- 返回:
判断对错,取决于函数是否被删除。
注销用户定义的标量函数。
- 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()
. 如果主数据库当前已连接,则附加的数据库将从打开的连接中分离。
- transaction([lock_type=None])
- 参数:
lock_type (str) -- 锁定策略:延迟、立即、独占。
使用指定的锁定策略(默认为延迟)创建事务上下文管理器。
- 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”。
- 返回:
没有返回值。
在当前连接上设置时区。如果没有打开的连接,则会打开一个。
- class MySQLDatabase(database[, **kwargs])
MySQL数据库实现。
查询生成器
- class Node
构成SQL查询的AST的所有组件的基类。
- static copy(method)
修饰器,用于改变节点状态的节点方法。这允许方法链接,例如:
query = MyModel.select() new_query = query.where(MyModel.field == 'value')
- unwrap()
用于递归展开“已包装”节点的API。基本情况是回归自我。
- is_alias()
用于确定用户是否已显式地为节点命名的API。
- class Source([alias=None])
行元组的源,例如表、联接或选择查询。默认情况下,提供名为“c”的“magic”属性,该属性是列/属性查找的工厂,例如:
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
.
- __add__(dest)
在上执行左外部联接
dest
.
- __sub__(dest)
在上执行右外部联接
dest
.
- __or__(dest)
对执行完全外部联接
dest
.
- __mul__(dest)
对执行交叉联接
dest
.
- class Table(name[, columns=None[, primary_key=None[, schema=None[, alias=None]]]])
表示数据库中的表(或类似于表的对象,如视图)。
- 参数:
name (str) -- 数据库表名
columns (tuple) -- 列名列表(可选)。
primary_key (str) -- 主键列的名称。
schema (str) -- 用于访问表的架构名称(如有必要)。
alias (str) -- 用于SQL查询中表的别名。
备注
如果指定了列,则将禁用magic“c”属性。
当没有显式定义列时,表有一个特殊的属性“c”,它是一个提供对表列动态访问的工厂。
例子::
User = Table('users') query = (User .select(User.c.id, User.c.username) .order_by(User.c.username))
列时的等效示例 are 明确规定::
User = Table('users', ('id', 'username')) query = (User .select(User.id, User.username) .order_by(User.username))
- bind([database=None])
- 参数:
database --
Database
对象。
将此表绑定到给定的数据库(或保留为空取消绑定)。
当桌子是 bound 对于数据库,可以对其执行查询,而无需在查询的执行方法中指定数据库。
- 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 -- 字典将列映射到值,生成字典(即列表)的iterable,或
Select
查询。columns (list) -- 当要插入的数据不是字典时要插入的列的列表。
kwargs -- 列名称到值的映射。
创建一个
Insert
查询到表中。
- class Join(lhs, rhs[, join_type=JOIN.INNER[, on=None[, alias=None]]])
表示到类表对象之间的联接。
- 参数:
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
类列的对象、属性或表达式的基类。
类列对象可以使用各种运算符和特殊方法组成。
&
:逻辑与|
逻辑或+
加成-
减法*
:乘法/
师^
异或==
平等!=
不等式>
大于<
:小于>=
:大于或等于<=
:小于或等于<<
:IN
>>
:IS
(即IS NULL
)%
:LIKE
**
:ILIKE
bin_and()
二进制和bin_or()
二进制或in_()
:IN
not_in()
:NOT IN
regexp()
:REGEXP
is_null(True/False)
:IS NULL
orIS 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) -- 对空值排序(第一个或最后一个)。
- 返回:
上升的
Ordering
列的对象。
- class Negated(node)
表示一个否定的类似列的对象。
- class Value(value[, converterNone[, unpack=True]])
- 参数:
value -- python对象或标量值。
converter -- 用于将值转换为数据库能理解的类型的函数。
unpack (bool) -- 列表或元组是应解包到值列表中还是按原样处理。
要在参数化查询中使用的值。调用者的责任是确保传入的值可以适应数据库驱动程序理解的类型。
- 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) -- 对空值排序(第一个或最后一个)。
表示按类似列的对象排序。
PostgreSQL支持非标准子句(“nulls first/last”)。Peewee将自动使用等效的
CASE
不支持此操作的数据库的语句(sqlite/mysql)。- 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) -- 约束名称。
表示检查约束。
警告
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表达式以确定哪些行被送入聚合函数。Postgres和SQLite支持此SQL功能。
- coerce([coerce=True])
- 参数:
coerce (bool) -- 是否尝试将函数调用结果强制为python数据类型。
胁迫时
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()
Helper实际上是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 -- A
SQL
表示窗口范围开始的实例或字符串。end -- A
SQL
表示窗口范围结束的实例或字符串。frame_type (str) --
Window.RANGE
,Window.ROWS
或Window.GROUPS
.extends -- A
Window
要扩展的定义。或者,您可以指定窗口的别名。exclude -- 帧排除,其中一个
Window.CURRENT_ROW
,Window.GROUP
,Window.TIES
或Window.NO_OTHERS
.alias (str) -- 窗口的别名。
表示window子句。
备注
有关将窗口函数与peewee一起使用的深入指南,请参见 窗口功能 部分。
- RANGE
- ROWS
- GROUPS
指定窗口
frame_type
. 见 帧类型:范围vs行vs组 .
- CURRENT_ROW
引用当前行以在start/end子句或帧排除参数中使用。
- NO_OTHERS
- GROUP
- TIES
指定窗口框架排除参数。
- static preceding([value=None])
- 参数:
value -- 前面的行数。如果
None
是无界的。
生成适合作为
start
窗口范围的参数。
- static following([value=None])
- 参数:
value -- 后面的行数。如果
None
是无界的。
生成适合作为
end
窗口范围的参数。
- 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 -- 用于事例查询的谓词(可选)。
expression_tuples -- 要评估的一个或多个案例。
default -- 默认值(可选)。
- 返回:
案件陈述的陈述。
实例:
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样式查找的任意筛选表达式。
表示适用于
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 -- 一个列的列表,其值应从原始插入中保留。也见
EXCLUDED
.where -- 用于限制冲突解决的表达式。
conflict_target -- 构成约束的列。
conflict_where -- 如果约束目标是部分索引(带WHERE子句的索引),则需要匹配该约束目标的表达式。
conflict_constraint (str) -- 用于冲突解决的约束的名称。目前只有Postgres支持。
表示数据修改查询的冲突解决子句。
根据所使用的数据库驱动程序,可能需要上述一个或多个参数。
- preserve(*columns)
- 参数:
columns -- 应保留其值的列。
- update([_data=None[, **kwargs]])
- 参数:
_data (dict) -- 字典将列映射到新值。
kwargs -- 将列名映射到新值的字典。
这个
update()
方法支持使用列到值的字典调用, or 表示相同的关键字参数。
- 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 -- 接受行dict并返回任意对象的函数。
使用给定的构造函数将行作为任意对象返回。
- sql()
- 返回:
由查询的SQL和参数组成的2元组。
- execute(database)
- 参数:
database (Database) -- 要对其执行查询的数据库。如果查询以前绑定到数据库,则不需要。
执行查询并返回结果(取决于正在执行的查询类型)。例如,select查询返回结果将是对查询结果的迭代器。
- 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) -- 限制条款的值。
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表达式一起进行和运算。
示例选择用户名等于“someone”的用户:
sq = User.select().where(User.username == 'somebody')
示例选择由编辑或管理员用户发出的推文:
sq = Tweet.select().join(User).where( (User.is_editor == True) | (User.is_admin == True))
不再活动的用户删除tweet的示例:
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()
呼叫是可链接的。多个呼叫将“和”一起进行。
- orwhere(*expressions)
- 参数:
expressions -- 要包含在WHERE子句中的零个或多个表达式。
在查询的WHERE子句中包含给定表达式。此方法与
Query.where()
方法,但表达式将与以前指定的任何Where表达式一起使用或与之一起使用。
- order_by(*values)
- 参数:
values -- 零个或多个类似于要排序的对象的列。
定义ORDER BY子句。任何先前指定的值都将被覆盖。
- order_by_extend(*values)
- 参数:
values -- 零个或多个类似于要排序的对象的列。
用给定的值扩展先前指定的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) -- 每页行数。
以更直观的方式指定限制和偏移的方便方法。
此功能设计时考虑了网站分页,因此第一页以
page=1
.
- class SelectQuery
选择实现用于创建复合查询的运算符重载的查询帮助器类。
- 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"
这个
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)
创建union all查询
dest
.
- __add__(dest)
创建union all查询
dest
.
- union(dest)
使用创建联合查询
dest
.
- __or__(dest)
使用创建联合查询
dest
.
- intersect(dest)
使用创建交叉查询
dest
.
- __and__(dest)
使用创建交叉查询
dest
.
- except_(dest)
使用创建except查询
dest
. 注意,方法名后面有一个“u”字符,因为except
是python保留字。
- __sub__(dest)
使用创建except查询
dest
.
- 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
,则返回行DICT。
从结果的第一行返回一个标量值。如果预期有多个标量值(例如单个查询中的多个聚合),则可以指定
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) -- 选择或复合选择查询。
op (str) -- 操作(例如联合、交叉、除外)。
rhs (SelectBase) -- 选择或复合选择查询。
表示复合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 -- 布尔值或str,指示是否选择…进行更新。
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”,该属性对应于生成的tweet数: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(*columns)
- 参数:
columns -- 零个或多个与要选择的对象类似的列。
等同于
Select.columns()
,提供向后兼容性。
- select_extend(*columns)
- 参数:
columns -- 零个或多个与要选择的对象类似的列。
用给定的列扩展当前所选内容。
例子:
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) -- 连接类型,默认为“内部”。
on (Expression) -- 联接谓词。
联接类型可以是以下类型之一:
JOIN.INNER
JOIN.LEFT_OUTER
JOIN.RIGHT_OUTER
JOIN.FULL
JOIN.FULL_OUTER
JOIN.CROSS
快速加入:
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 -- 零个或多个与要分组的对象类似的列。
定义group by子句。任何先前指定的值都将被覆盖。
此外,要指定给定表上的所有列,可以传递表/模型对象来代替各个列。
例子:
query = (User .select(User, fn.Count(Tweet.id).alias('count')) .join(Tweet) .group_by(User))
- group_by_extend(*columns)
- 参数:
values -- 零个或多个与要分组的对象类似的列。
用给定的列扩展group by子句。
- having(*expressions)
- 参数:
expressions -- 要包含在HAVING子句中的零个或多个表达式。
在查询的HAVING子句中包含给定表达式。表达式将与以前指定的具有表达式的任何表达式一起进行和运算。
- distinct(*columns)
- 参数:
columns -- 零个或更多类似于列的对象。
指示此查询是否应使用distinct子句。通过指定单个值
True
查询将使用简单的select distinct。指定一列或多列将导致上的select distinct。
- window(*windows)
- 参数:
windows -- 零或更多
Window
物体。
定义window子句。任何先前指定的值都将被覆盖。
例子:
# 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 -- 用于返回子句的零个或多个类似于列的对象
指定查询的返回子句(如果数据库支持)。
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) -- 要更新的数据。
表示更新查询的类。
例子:
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
加入
使用更新指定要联接的其他表…来自Postgres支持的语法。这个 Postgres documentation 提供其他详细信息,但要总结:
当A
FROM
子句存在,实际上发生的是将目标表联接到“自”列表中提到的表,并且联接的每个输出行表示目标表的更新操作。使用时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 -- 冲突解决策略。
表示插入查询的类。
- as_rowcount([as_rowcount=True])
- 参数:
as_rowcount (bool) -- 是否返回修改后的行数(而不是最后插入的行ID)。
默认情况下,在执行以下操作的数据库上 not 使用自动返回(当前是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_replace([replace=True])
- 参数:
replace (bool) -- 是否添加冲突替换子句。
指定替换冲突解决策略。
- on_conflict([action=None[, update=None[, preserve=None[, where=None[, conflict_target=None[, conflict_where=None[, conflict_constraint=None]]]]]]])
- 参数:
action (str) -- 解决冲突时要采取的操作。如果为空,则假定操作为“更新”。
update -- 将列映射到新值的字典。
preserve -- 一个列的列表,其值应从原始插入中保留。
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
表示删除查询的类。
- class Index(name, table, expressions[, unique=False[, safe=False[, where=None[, using=None]]]])
- 参数:
name (str) -- 索引名称。
table (Table) -- 要在其上创建索引的表。
expressions -- 要索引的列列表(或表达式)。
unique (bool) -- 索引是否唯一。
safe (bool) -- 是否添加if not exists子句。
where (Expression) -- 索引的可选WHERE子句。
using (str) -- 索引算法。
- safe([_safe=True])
- 参数:
_safe (bool) -- 是否添加if not exists子句。
- where(*expressions)
- 参数:
expressions -- 要包含在WHERE子句中的零个或多个表达式。
在索引的WHERE子句中包含给定表达式。表达式将与以前指定的任何where表达式一起进行和运算。
- 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) -- 索引是否唯一。
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)
领域
- 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) -- 字段允许空值。
index (bool) -- 在字段上创建索引。
unique (bool) -- 在字段上创建唯一索引。
column_name (str) -- 为字段指定列名。
default -- 默认值(在python中强制执行,而不是在服务器上)。
primary_key (bool) -- 字段是主键。
constraints (list) -- 要应用于列的约束列表,例如:
[Check('price > 0')]
.sequence (str) -- 字段的序列名。
collation (str) -- 字段的排序规则名称。
unindexed (bool) -- 声明字段未索引(仅限于sqlite)。
choices (list) -- 两元组的一个表,将列值映射到显示标签。例如,仅用于元数据目的,以帮助显示字段值选项的下拉列表。
help_text (str) -- 字段的帮助文本,仅用于元数据。
verbose_name (str) -- 字段的详细名称,仅用于元数据。
index_type (str) -- 指定索引类型(仅限Postgres),例如“brin”。
域上的
Model
类似于表中的列。- 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 data type
- class IntegerField
用于存储整数的字段类。
- class BigIntegerField
用于存储大整数的字段类(如果数据库支持)。
- class SmallIntegerField
用于存储小整数的字段类(如果数据库支持)。
- class AutoField
用于存储自动递增主键的字段类。
备注
在sqlite中,出于性能原因,默认的主键类型只使用最大现有值+1作为新值,而不是最大值+1。这意味着删除的记录可以重用其主键。与默认情况下禁用外键的sqlite结合使用(即忽略删除时的含义,即使您显式地指定了它),这可能会导致意外和危险的行为。为了避免这种情况,您可能需要使用
AutoIncrementField
和pragmas=[('foreign_keys', 'on')]
当你实例化SqliteDatabase
.
- class BigAutoField
字段类,用于存储使用64位的自动递增主键。
- class IdentityField([generate_always=False])
- 参数:
generate_always (bool) -- 如果指定,则标识将始终生成(并且在插入期间显式指定值将引发编程错误)。否则,只在需要时生成标识值。
字段类,用于使用新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) -- 自动舍入值。
rounding -- 默认为
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)
- 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- 是否设置了位。
- class UUIDField
用于存储的字段类
uuid.UUID
物体。对于Postgres,基础列的数据类型将为 UUID. 由于sqlite和mysql没有本机UUID类型,因此UUID存储为 VARCHAR 相反。
- class BinaryUUIDField
用于存储的字段类
uuid.UUID
以16字节为单位的有效对象。使用数据库的 BLOB 数据类型(或 VARBINARY 在MySQL中,或 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()
.只需注意 year , 月 和 day 对…有意义DateField
.
- 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的幂得到整数来支持。
If the
resolution
parameter is0
or1
, then the timestamp is stored using second resolution. A resolution between2
and6
is treated as the number of decimal places, e.g.resolution=3
corresponds to milliseconds. Alternatively, the decimal can be provided as a multiple of 10, such thatresolution=10
will store 1/10th of a second resolution.这个
resolution
参数可以是0-6 or 10、100等,最高1000000(微秒分辨率)。这允许在使用IntegerField
用于储存。默认为第二分辨率。还接受布尔参数
utc
,用于指示时间戳是否应为UTC。默认是False
.最后,领域
default
是当前时间戳。如果不希望此行为,则显式传入default=None
.
- class IPField
用于高效存储IPv4地址的字段类(整数)。
- class BooleanField
用于存储布尔值的字段类。
- class BareField([coerce=None[, **kwargs]])
- 参数:
coerce -- 用于将原始值转换为特定格式的可选函数。
不指定数据类型的字段类(sqlite only)。
由于数据类型不是强制的,因此可以声明字段 any 数据类型。对于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) -- 删除操作时,例如
'CASCADE'
…on_update (str) -- 更新操作时。
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
,因为不会发生默认的删除行为(在不修改数据的情况下失败),您的数据可以自动重新链接。最安全的做法是指定pragmas={{'foreign_keys': 1}}
当你实例化SqliteDatabase
.
- 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()
In cases like these you should use the regular
ForeignKeyField
or you can manually resolve deferred foreign keys like so:# 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
旨在通过提供 field-like 用于查询和修改联接表中数据的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
参数。如果Athrough_model
未指定,将自动创建一个。为使用
ManyToManyField
, 必须专门创建through表.# 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
如果由于依赖关系,不能在不引入名称错误的情况下声明模型或多对多字段,则为通过模型的占位符。
例子:
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')
模式管理器
- class SchemaManager(model[, database=None[, **context_options]])
-
提供用于管理为给定模型创建和删除表和索引的方法。
- create_table([safe=True[, **options]])
- 参数:
safe (bool) -- 指定if not exists子句。
options -- 任意选项。
对给定模型执行创建表查询。
- drop_table([safe=True[, drop_sequences=True[, **options]]])
- 参数:
safe (bool) -- 指定if exists子句。
drop_sequences (bool) -- 删除与表中的列关联的任何序列(仅限Postgres)。
options -- 任意选项。
对给定模型执行删除表查询。
- truncate_table([restart_identity=False[, cascade=False]])
- 参数:
restart_identity (bool) -- 重新启动ID序列(仅限Postgres)。
cascade (bool) -- 同时截断相关表(仅限Postgres)。
对给定模型执行truncate table。如果数据库是不支持截断的sqlite,那么将执行等效的删除查询。
- create_indexes([safe=True])
- 参数:
safe (bool) -- 指定if not exists子句。
为为模型定义的索引执行创建索引查询。
- drop_indexes([safe=True])
- 参数:
safe (bool) -- 指定if exists子句。
对为模型定义的索引执行删除索引查询。
- 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) -- 是否指定不存在。
为模型创建序列、索引和表。
- drop_all([safe=True[, drop_sequences=True[, **options]]])
- 参数:
safe (bool) -- 是否指定是否存在。
drop_sequences (bool) -- 删除与表中的列关联的任何序列(仅限Postgres)。
options -- 任意选项。
删除模型和关联索引的表。
模型
- 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) -- 指定不带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 Model(**kwargs)
- 参数:
kwargs -- 字段名到值的映射以初始化模型。
模型类为使用数据库表提供了高级抽象。模型是与数据库表(或类似于表的对象,如视图)的一对一映射。的子类
Model
声明任意数量的Field
实例作为类属性。这些字段对应于表中的列。表级操作,例如
select()
,update()
,insert()
和delete()
实现为类方法。行级操作,例如save()
和delete_instance()
实现为InstanceMethods。例子:
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
查询。
创建选择查询。如果没有显式提供字段,则查询将默认选择模型上定义的所有字段,除非将查询用作子查询,在这种情况下,默认情况下只选择主键。
选择所有列的示例:
query = User.select().where(User.active == True).order_by(User.username)
选择上所有列的示例 Tweet 以及父模型, User. 当
user
在上访问外键 Tweet 实例不需要其他查询(请参见 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 -- 字段名到值的映射。
创建更新查询。
显示用户在注册过期时被标记为不活动的示例:
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
字典。显示创建新用户的示例:
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 -- 生成要插入的行的ITable。
fields (list) -- 正在插入的字段列表。
- 返回:
修改的行数(见注释)。
插入多行数据。
这个
rows
参数必须是可生成字典或元组的iterable,其中元组值的顺序与中指定的字段相对应。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
参数可以是任意的iterable,也可以使用生成器:def get_usernames(): for username in ['charlie', 'huey', 'peewee']: yield {'username': username} User.insert_many(get_usernames()).execute()
警告
如果使用的是sqlite,则sqlite库必须是3.7.11或更高版本才能利用大容量插入。
备注
SQLite对每个语句的绑定变量有一个默认限制。此限制可以在编译时或运行时修改, but 如果在运行时修改,则只能指定 降低 值大于默认限制。
有关详细信息,请查看以下sqlite文档:
备注
默认返回值是修改的行数。但是,在使用Postgres时,Peewee将默认返回一个游标,该游标生成插入行的主键。要在Postgres中禁用此功能,请使用空调用
returning()
.
- classmethod insert_from(query, fields)
- 参数:
query (Select) -- 选择要用作数据源的查询。
fields -- 要插入数据的字段。
- 返回:
修改的行数(见注释)。
使用select查询作为源插入数据。此API应用于*insert into…从…*中选择。
为非规范化目的跨表插入数据的示例:
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中禁用此功能,请使用空调用
returning()
.
- classmethod replace([__data=None[, **insert]])
- 参数:
__data (dict) --
dict
字段到要插入的值。insert -- 字段名到值的映射。
创建使用replace解决冲突的插入查询。
见
Model.insert()
举个例子。
- classmethod replace_many(rows[, fields=None])
- 参数:
rows -- 生成要插入的行的ITable。
fields (list) -- 正在插入的字段列表。
使用替换来解决冲突,插入多行数据。
见
Model.insert_many()
举个例子。
- classmethod raw(sql, *params)
- 参数:
sql (str) -- 要执行的SQL查询。
params -- 用于查询的参数。
直接执行SQL查询。
从用户表中选择行的示例:
q = User.raw('select id, username from users') for user in q: print(user.id, user.username)
备注
一般使用
raw
为那些可以显著优化select查询的情况保留。它对于选择查询很有用,因为它将返回模型的实例。
- classmethod 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通常对查询的绑定参数有限制,因此最大批处理大小应为param limit/字段数。对于Sqlite<3.32.0,此限制通常为999,对于较新版本,此限制为32766。
当提供批量大小时, strongly recommended 在事务或保存点中使用
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。
当提供批量大小时, strongly recommended 在事务或保存点中使用
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 -- 创建新行时使用的默认值。
- 返回:
Tuple
Model
实例和布尔值,指示是否创建了新对象。
尝试获取与给定筛选器匹配的行。如果找不到匹配行,请创建新行。
警告
使用此方法时,可能存在竞争条件。
例子 without
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) -- 强制插入查询。
only (list) -- 只保存给定的
Field
实例。
- 返回:
修改的行数。
在模型实例中保存数据。默认情况下,主键值的存在将导致执行更新查询。
显示保存模型实例的示例:
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)
.如果你 always 要只保存模型的脏字段,可以使用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
可以为空的关系将设置为空。
删除给定的实例。任何设置为删除时层叠的外键都将自动删除。对于更多的编程控件,可以指定
recursive=True
,这将删除任何不可为空的相关模型(那些 are Nullable将设置为空)。如果要删除所有依赖项,不管它们是否可以为空,请设置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) -- 索引是否唯一。
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) -- 通过可以为空的外键相关的搜索模型
- 返回类型:
Generator expression yielding queries and foreign key fields.
生成依赖模型的查询列表。生成包含查询和相应的外键字段的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 -- 要选择的字段或模型类的列表。
选择查询的特定于模型的实现。
- switch([ctx=None])
- 参数:
ctx -- A
Model
,ModelAlias
、子查询或联接的其他对象。
切换 join context -后续调用的源
join()
将加入反对。用于针对单个表指定多个联接。如果
ctx
如果没有给出,则将使用查询的模型。下面的示例从tweet中选择,并在用户和tweet标志上加入:
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 -- A
Model
,ModelAlias
,Select
查询或要联接到的其他对象。join_type (str) -- 连接类型,默认为内部。
on -- 连接谓词或
ForeignKeyField
加入。src -- 显式指定联接的源。如果未指定,则当前 join context 将被使用。
attr (str) -- 从联接模型投影列时使用的属性。
与另一个类似表的对象联接。
联接类型可以是以下类型之一:
JOIN.INNER
JOIN.LEFT_OUTER
JOIN.RIGHT_OUTER
JOIN.FULL
JOIN.FULL_OUTER
JOIN.CROSS
示例选择tweets并加入用户,以便仅限于“admin”用户发出的tweets:
sq = Tweet.select().join(User).where(User.is_admin == True)
示例选择用户并加入特定的外键字段。见 example app 对于实际使用:
sq = User.select().join(Relationship, on=Relationship.to_user)
有关外键、联接和模型之间关系的深入讨论,请参阅 关系和连接 .
- join_from(src, dest[, join_type='INNER'[, on=None[, attr=None]]])
- 参数:
src -- 联接的源。
dest -- 要联接到的表。
使用与非特定模型相同的参数顺序
join()
. 绕过 join context 要求指定联接源。
- 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)
要有效地执行反向操作、查询用户及其tweet,可以使用预取:
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) -- 让经理知道一个新的来源。如果已添加源,则调用为no-op。
- get(source[, any_depth=False])
返回当前作用域中源的别名。如果源没有别名,则会给出下一个可用的别名。
- 参数:
source (Source) -- 应检索其别名的源。
- 返回:
别名已分配给源,或下一个可用别名。
- 返回类型:
str
- push()
将新作用域推到堆栈上。
- pop()
从堆栈中弹出范围。
- class State(scope[, parentheses=False[, subquery=False[, **kwargs]]])
用于在给定范围内表示状态的轻型对象。在SQL生成期间,
Context
可以检查状态。这个State
类允许peewee执行以下操作:对字段类型或SQL表达式使用公共接口,但使用特定于供应商的数据类型或运算符。
编译一
Column
实例转换为完全限定的属性,如命名别名等,具体取决于scope
.确保正确使用括号。
- 参数:
scope (int) -- 状态处于活动状态时要应用的作用域规则。
parentheses (bool) -- 将包含的SQL括在括号中。
subquery (bool) -- 当前状态是否为外部查询的子级。
kwargs (dict) -- 应在当前状态下应用的任意设置。
- class Context(**settings)
将Peewee结构转换为参数化SQL查询。
Peewee结构应全部实现 __sql__ 方法,将由 Context 在SQL生成期间初始化。这个 __sql__ 方法接受单个参数, Context 实例,允许对范围和状态进行递归下降和内省。
- scope
返回当前活动的作用域规则。
- parentheses
返回当前状态是否用括号括起来。
- subquery
返回当前状态是否为其他查询的子级。
- scope_normal([**kwargs])
默认范围。源由别名引用,列由源中的点路径引用。
- scope_source([**kwargs])
定义源时使用的范围,例如在列列表和select查询的FROM子句中。此范围用于定义源的完全限定名并分配别名。
- scope_values([**kwargs])
用于更新、插入或删除查询的范围,其中,我们不通过别名引用源,而是直接引用它。同样,由于只有一个表,所以不需要用点路径引用列。
- scope_cte([**kwargs])
生成公用表表达式内容时使用的范围。在WITH语句之后,在为CTE生成定义时使用(而不仅仅是对一个定义的引用)。
- scope_column([**kwargs])
为列生成SQL时使用的范围。确保使用正确的别名呈现列。因为在引用子select的内部投影时,peewee会将完整的select查询呈现为列的“源”(而不是查询的别名+)。+柱)。这个范围允许我们避免在只需要别名时呈现完整的查询。
- sql(obj)
将可组合节点对象、子上下文或其他对象追加到查询AST。python值(如整数、字符串、浮点数等)被视为参数化值。
- 返回:
更新的上下文对象。
- literal(keyword)
将字符串文本附加到当前查询ast。
- 返回:
更新的上下文对象。
- query()
- 返回:
由上下文的(sql,参数)组成的2元组。
常量和助手
- class Proxy
为另一个对象创建代理或占位符。
- initialize(obj)
- 参数:
obj -- 要代理到的对象。
将代理绑定到给定对象。之后,代理上的所有属性查找和方法调用都将发送到给定的对象。
将调用任何已注册的回调。
- attach_callback(callback)
- 参数:
callback -- 接受单个参数(绑定对象)的函数。
- 返回:
自己
添加要在初始化代理时执行的回调。
- chunked(iterable, n)
- 参数:
iterable -- 作为要分块的数据源的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