文章目录
- 11.5.5 class Model
- classmethod alias([alias=None])
- classmethod select(*fields)
- classmethod update([__data=无[, **update ]])
- classmethod insert([__data=None[, **insert ]])
- classmethod insert_many(rows [,fields =None])
- classmethod insert_from(query,fields)
- classmethod replace([__data=None[, **insert ]])
- classmethod replace_many(rows[, fields=None])
- classmethod raw( sql , *params )
- classmethod delete()
- classmethod create( **query)
- classmethod bulk_create(model_list[, batch_size=None])
- classmethod bulk_update(model_list, fields[, batch_size=None])
- classmethod get(*query, **filters)
- classmethod get_or_none(*query, **filters)
- classmethod get_by_id( PK )
- classmethod set_by_id(key ,value)
- classmethod delete_by_id( PK )
- classmethod get_or_create( **kwargs )
- classmethod filter( *dq_nodes , **filters )
- get_id()
- save([force_insert=False[,only=None]])
- dirty_fields
- is_dirty()
- classmethod bind(database[, bind_refs=True[, bind_backrefs=True]])
- classmethod bind_ctx(database[, bind_refs=True[, bind_backrefs=True]])
- classmethod table_exists()
- classmethod create_table([safe=True[, **options]])
- classmethod drop_table([safe=True[, **options]])
- truncate_table([restart_identity=False[,cascade=False]])
- classmethod index(*fields[, unique=False[, safe=True[, where=None[, using=None[, name=None]]]]])
- classmethod add_index(*args, **kwargs)
- dependencies([search_nullable=False])
- __iter__ ()
- __len__ ()
11.5.5 class Model
class Model( **kwargs )
参数: kwargs– 将字段名称映射到值以初始化model。
model类为处理数据库表提供了高级抽象。model是与数据库表(或类似表的对象,例如视图)的一对一映射。的子类将Model任意数量的Field实例声明为类属性。这些字段对应于表中的列。
表级操作, 例如select()、 update()和被实现为classmethod 。行级操作,例如和 被实现为实例方法。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类的别名。model别名允许您Model在查询中多次引用相同的内容,例如在执行自联接或子查询时。
例子:
Parent = Category.alias()
sq = (Category.select(Category, Parent).join(Parent, on=(Category.parent == Parent.id)).where(Parent.name == 'parent category'))
classmethod select(*fields)
参数: 字段– model类、字段实例、函数或表达式的列表。如果未提供参数,则默认选择给定model的所有列。
返回: ModelSelect询问。
创建一个 SELECT 查询。如果没有明确提供字段,则默认情况下查询将选择model上定义的所有字段,除非您将查询用作子查询,在这种情况下,默认情况下只会选择主键。
选择所有列的示例:
query = User.select().where(User.active == True).order_by(User.username)
选择Tweet和父model User上的所有列的示例。当在Tweetuser实例上访问外键时, 不需要额外的查询(请参阅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=无[, **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 查询。
在数据库中插入一个新行。insert如果model上的任何字段具有默认值,则如果未在字典中明确设置字段,则将使用这些值。
显示创建新用户的示例:
q = User.insert(username='admin', active=True, registration_expired=False)
q.execute() # perform the insert.
您还可以使用Field对象作为键:
new_id = User.insert({User.username: 'admin'}).execute()
如果您的model在其中一个字段上具有默认值,并且该字段未在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 文档:
最大变量数限制
更改运行时限制
SQLite 编译时标志
笔记
默认返回值是修改的行数。但是,当使用 Postgres 时,Peewee 默认会返回一个游标,该游标会产生插入行的主键。要使用 Postgres 禁用此功能,请使用对returning().
classmethod insert_from(query,fields)
参数:
query( 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 禁用此功能,请使用对returning().
classmethod replace([__data=None[, **insert ]])
参数:
__data ( dict ) –dict字段到要插入的值。
insert – 字段名称到值的映射。
创建一个使用 REPLACE 解决冲突的 INSERT 查询。
请参阅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保留用于可以显着优化选择查询的情况。它对于选择查询很有用,因为它将返回model的实例。
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– 字段名称到值的映射。
在表中插入新行并返回相应的model实例。
显示创建用户的示例(将向数据库添加一行):
user = User.create(username='admin', password='test')
笔记
create() 方法是实例化然后保存的简写。
classmethod bulk_create(model_list[, batch_size=None])
参数:
model_list ( iterableModel ) – 未保存实例的列表或其他可迭代 对象。
batch_size ( int ) – 每次插入要批处理的行数。如果未指定,所有model都将插入到单个查询中。
返回:
没有返回值。
有效地将多个未保存的model实例插入数据库。与insert_many()接受行数据作为字典或列表的列表不同,此方法接受未保存的model实例的列表。
例子:
# 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)
警告
RETURNING 仅当您使用 Postgresql(支持该子句)时,才会设置新创建model的主键值。
SQLite 通常对查询的绑定参数有限制,因此最大批量大小应该是 param-limit / number-of-fields。对于 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 ) – 每次插入要批处理的行数。如果未指定,所有model都将插入到单个查询中。
返回:
更新的总行数。
有效地更新多个model实例。
例子:
# 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])
如果您有大量对象要更新,强烈建议您指定 abatch_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
返回:
与指定过滤器匹配的model实例。
检索与给定过滤器匹配的单个model实例。如果没有返回model,DoesNotExist则引发 a。
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匹配给定的过滤器,则与相同Model.get()但返回。None
classmethod get_by_id( PK )
参数: PK– 主键值。
调用Model.get()通过主键指定查找的简写。引发DoesNotExist具有给定主键值的 if 实例不存在。
例子:
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()
返回: model实例的主键。
save([force_insert=False[,only=None]])
参数:
force_insert ( bool ) – 强制插入查询。
only ( list ) – 只保存给定的Field实例。
返回:
修改的行数。
将数据保存在model实例中。默认情况下,主键值的存在将导致执行 UPDATE 查询。
显示保存model实例的示例:
user = User()
user.username = 'some-user' # does not touch the database
user.save() # change is persisted to the db
dirty_fields
dirty_fields
返回已修改字段的列表。
返回类型: 列表
笔记
如果您只想保留修改后的字段,可以调用 model.save(only=model.dirty_fields).
如果您总是只想保存model的脏字段,可以使用 Meta 选项。然后,任何时候调用,默认情况下只会保存脏字段,例如only_save_dirty = TrueModel.save()
class Person(Model):first_name = CharField()last_name = CharField()dob = DateField()class Meta:database = dbonly_save_dirty = True
警告
Peewee 通过观察何时在model实例上设置字段属性来确定字段是否“脏”。如果该字段包含一个可变的值,例如字典实例,并且该字典随后被修改,Peewee 将不会注意到更改。
is_dirty()
返回布尔值,指示是否手动设置了任何字段。
delete_instance([recursive=False[, delete_nullable=False]])
参数:
recursive ( bool ) – 删除相关model。
delete_nullable ( bool ) – 删除具有空外键的相关model。如果False可以为空的关系将设置为 NULL。
删除给定的实例。任何设置为删除时级联的外键都将被自动删除。对于更多的编程控制,您可以指定recursive=True,这将删除任何不可为空的相关model(那些可以为空的将被设置为 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 ) – 绑定相关model。
bind_backrefs ( bool ) – 绑定反向引用相关model。
将model(和指定的关系)绑定到给定的数据库。
另见:Database.bind()。
classmethod bind_ctx(database[, bind_refs=True[, bind_backrefs=True]])
Like bind(),但返回一个上下文管理器,它只在包装块的持续时间内绑定model。
另见:Database.bind_ctx()。
classmethod table_exists()
返回: 指示表是否存在的布尔值。
classmethod create_table([safe=True[, **options]])
参数: safe( bool ) – 如果设置为True,则创建表查询将包含一个子句。IF NOT EXISTS
创建model表、索引、约束和序列。
例子:
with database:SomeModel.create_table() # Execute the create table query.
classmethod drop_table([safe=True[, **options]])
参数: safe( bool ) – 如果设置为True,则创建表查询将包含一个子句。IF EXISTS
删除model表。
truncate_table([restart_identity=False[,cascade=False]])
参数:
restart_identity ( bool ) – 重新启动 id 序列(仅限 postgres)。
cascade ( bool ) – 也截断相关表(仅限 postgres)。
为model截断(删除所有行)。
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 ) – 可选索引名称。
用于在model上声明索引的表达方法。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 ': '值': '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()