foreign-keys - Peewee 我如何为依赖项调用 post_delete 信号?
问题描述
我看到 peewee 有信号http://docs.peewee-orm.com/en/latest/peewee/playhouse.html#signals
但它仅适用于delete_instance()
.
由于我希望是显而易见的原因,当您使用 Model.insert()、Model.update() 或 Model.delete() 方法时,Peewee 信号不起作用。这些方法会生成超出 ORM 范围执行的查询,并且 ORM 不知道在查询执行时哪些模型实例可能会或可能不会受到影响。
信号通过连接到更高级别的 peewee API 来工作,例如 Model.save() 和 Model.delete_instance(),其中受影响的模型实例是提前知道的。
那么,我如何在依赖关系的记录上使用信号,因为它使用delete()
依赖关系?
def delete_instance(self, recursive=False, delete_nullable=False):
if recursive:
dependencies = self.dependencies(delete_nullable)
for query, fk in reversed(list(dependencies)):
model = fk.model
if fk.null and not delete_nullable:
model.update(**{fk.name: None}).where(query).execute()
else:
model.delete().where(query).execute()
return type(self).delete().where(self._pk_expr()).execute()
解决方案
简短的回答是你不能,因为递归删除是使用以下形式的查询实现的:
DELETE FROM ... WHERE foreign_key_id = X
例如,假设您有一个用户,他们创建了 1000 条推文。tweet.user_id 指向 user.id。当您删除该用户时,peewee 会发出 2 个查询:
DELETE FROM tweets WHERE user_id = 123
DELETE FROM users WHERE id = 123
如果它打电话给delete_instance()
你,你最终会发出 1001 个查询。因此,希望很清楚为什么以这种方式实施它。
我建议,如果您要删除行并且需要对相关行执行某种清理,那么您最好进行软删除(例如,设置 a status=DELETED
)。然后处理信号 API 之外的任何关系。
推荐阅读
- rsa-archer-grc - 如何在工具栏内容下的订阅通知内的现有字段中添加字段?
- git - 从我的“.git/info/exclude”文件中包含的合并中排除文件的最佳方法是什么?
- docker - 运行可以通过 SSH 连接到的本地 docker 容器
- java - Java检查两个列表中有多少元素相同
- django - 如何将基本查询集与具有分组数据的查询集结合起来?
- reactjs - useState / useEffect 反应传播运算符的错误
- xml - 如何反序列化java Long哪个xml标签有xsi:nil?
- regex - solr 模式替换过滤器
- python - 将 2 个数据框合并为 1 个结果数据框
- c# - 尝试在 .NET Core 3.0 中同步执行 foreach 循环时出现明显问题