文章目录
11.2.31 class _WriteQuery
class _WriteQuery(table[, returning=None[, **kwargs]])
参数:
table ( Table ) – 要写入的表。
返回( list ) – RETURNING 子句的列列表。
写查询的基类。
returning( *returning)
参数: 返回– RETURNING 子句的零个或多个类似列的对象
指定查询的 RETURNING 子句(如果您的数据库支持)。
query = (User
.insert_many([{'username': 'foo'},
{'username': 'bar'},
{'username': 'baz'}])
.returning(User.id, User.username)
.namedtuples())
data = query.execute()
for row in data:
print('added:', row.username, 'with id=', row.id)
11.2.32 class Update
class Update(table[, update=None[, **kwargs]])
参数:
- Table ( Table ) – 要更新的表。
- update ( dict ) – 要更新的数据。
表示 UPDATE 查询的类。
例子:
PageView = Table('page_views')
query = (PageView
.update({PageView.c.page_views: PageView.c.page_views + 1})
.where(PageView.c.url == url))
query.execute(database)
from_(*sources)
参数: 来源( Source ) – 一个或多个Table, Model, 查询或ValuesList加入。
使用 Postgres 支持的 UPDATE … FROM 语法指定要加入的其他表。Postgres 文档提供了 更多详细信息,但总结一下:
当一个FROM子句存在时,本质上发生的事情是目标表连接到 from_list 中提到的表,连接的每个输出行代表目标表的更新操作。使用时,FROM您应确保连接最多为要修改的每一行生成一个输出行。
例子:
# Update multiple users in a single query.
data = [('huey', True),
('mickey', False),
('zaizee', True)]
vl = ValuesList(data, columns=('username', 'is_admin'), alias='vl')
# Here we'll update the "is_admin" status of the above users,
# "joining" the VALUES() on the "username" column.
query = (User
.update(is_admin=vl.c.is_admin)
.from_(vl)
.where(User.username == vl.c.username))
上述查询产生以下 SQL:
UPDATE "users" SET "is_admin" = "vl"."is_admin"
FROM (
VALUES ('huey', t), ('mickey', f), ('zaizee', t))
AS "vl"("username", "is_admin")
WHERE ("users"."username" = "vl"."username")
11.2.33 class Insert
class Insert(table[, insert=None[, columns=None[, on_conflict=None[, **kwargs]]]])
参数:
- table ( Table ) – 要将数据插入的表。
- insert – 字典、列表或查询。
- columns ( list ) – 当insert是列表或查询时的列列表。
- on_conflict – 冲突解决策略。
表示 INSERT 查询的类。
as_rowcount([as_rowcount=True])
参数: as_rowcount( bool ) – 是否返回修改后的行数(相对于最后插入的行 ID)。
默认情况下,在不自动使用 RETURNING 的数据库(当前为 Sqlite 和 MySQL)上,Peewee 版本 3.12 到 3.14.10 将在执行批量插入时返回修改后的行数。此更改已恢复,因此批量插入默认情况下将返回cursor.lastrowid.
如果您希望接收插入的行数,请指定 as_rowcount():
db = MySQLDatabase(...)
query = User.insert_many([...])
# By default, the last rowid is returned:
#last_id = query.execute()
# To get the modified row-count:
rowcount = query.as_rowcount().execute()
on_conflict_ignore([ignore=True])
参数: 忽视( bool ) – 是否添加 ON CONFLICT IGNORE 子句。
指定 IGNORE 冲突解决策略。
on_conflict_replace([replace=True])
参数: 代替( bool ) – 是否添加 ON CONFLICT REPLACE 子句。
指定 REPLACE 冲突解决策略。
on_conflict([action=None[, update=None[, preserve=None[, where=None[, conflict_target=None[, conflict_where=None[, conflict_constraint=None]]]]]]])
参数:
- action ( str ) – 解决冲突时要采取的行动。如果为空,则假定操作为“更新”。
-update – 字典映射列到新值。 - preserve - 列的列表,其值应从原始 INSERT 中保留。
- where - 限制冲突解决的表达式。
- conflict_target – 构成约束的列。
- conflict_where – 如果约束目标是部分索引(带有 WHERE 子句的索引),则需要匹配约束目标的表达式。
- conflict_constraint ( str ) – 用于解决冲突的约束名称。目前只有 Postgres 支持。
指定OnConflict用于解决冲突的子句的参数。
例子:
class User(Model):
username = TextField(unique=True)
last_login = DateTimeField(null=True)
login_count = IntegerField()
def log_user_in(username):
now = datetime.datetime.now()
# INSERT a new row for the user with the current timestamp and
# login count set to 1. If the user already exists, then we
# will preserve the last_login value from the "insert()" clause
# and atomically increment the login-count.
userid = (User
.insert(username=username, last_login=now, login_count=1)
.on_conflict(
conflict_target=[User.username],
preserve=[User.last_login],
update={User.login_count: User.login_count + 1})
.execute())
return userid
使用特殊命名空间的示例EXCLUDED:
class KV(Model):
key = CharField(unique=True)
value = IntegerField()
# Create one row.
KV.create(key='k1', value=1)
# Demonstrate usage of EXCLUDED.
# Here we will attempt to insert a new value for a given key. If that
# key already exists, then we will update its value with the *sum* of its
# original value and the value we attempted to insert -- provided that
# the new value is larger than the original value.
query = (KV.insert(key='k1', value=10)
.on_conflict(conflict_target=[KV.key],
update={KV.value: KV.value + EXCLUDED.value},
where=(EXCLUDED.value > KV.value)))
# Executing the above query will result in the following data being
# present in the "kv" table:
# (key='k1', value=11)
query.execute()
# If we attempted to execute the query *again*, then nothing would be
# updated, as the new value (10) is now less than the value in the
# original row (11).
11.2.34 class Delete
class Delete
表示 DELETE 查询的类。
11.2.35 class Index
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])
参数: _安全的( bool ) – 是否添加 IF NOT EXISTS 子句。
where(*expressions)
参数: 表达式– 要包含在 WHERE 子句中的零个或多个表达式。
在索引的 WHERE 子句中包含给定的表达式。这些表达式将与任何先前指定的 WHERE 表达式一起进行 AND 运算。
using([_using=None])
参数: _使用( str ) – 为 USING 子句指定索引算法。
11.2.36 class ModelIndex
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)