python - 在 Django 的 ORM 中使用带有 UPDATE 的子查询
问题描述
假设我有两个模型,我将它们称为ModelA
和ModelB
。两种模型都有一些共同的领域,(由field_one
、field_two
和表示field_three
)。此外,ModelB
还有一个外键ModelA
.
class ModelA(Model):
field_one = models.IntegerField()
field_two = models.TextField()
field_three = models.BooleanField()
class ModelB(Model):
field_one = models.IntegerField()
field_two = models.TextField()
field_three = models.BooleanField()
model_a = models.ForeignKey(ModelA, on_delete=models.CASCADE)
我需要更新所有实例ModelB
以将字段的值更新为关联ModelA
实例的值。我需要完全在数据库中执行此操作,而不需要实例化任何模型实例(不使用.save()
or bulk_update()
)。
我知道如何使用子查询在 PostgreSQL 中完成此操作:
UPDATE model_b SET (field_one, field_two, field_three) =
(SELECT field_one, field_two, field_three FROM model_a
WHERE model_b.model_a_id = model_a.id);
如何在 Django 的 ORM 中表达上述查询?
这是我能得到的最接近的:
ModelB.objects.update(
field_one=Subquery(ModelA.objects.filter(id=OuterRef('model_a_id')).values(field_one)[:1]),
field_two=Subquery(ModelA.objects.filter(id=OuterRef('model_a_id')).values(field_two)[:1]),
field_three=Subquery(ModelA.objects.filter(id=OuterRef('model_a_id')).values(field_three)[:1])
})
但是,这会导致每个字段都有一个子查询:
UPDATE model_b SET
field_one = (SELECT model_a.field_one FROM model_a WHERE model_a.id = model_b.model_a_id LIMIT 1),
field_two = (SELECT model_a.field_two FROM model_a WHERE model_a.id = model_b.model_a_id LIMIT 1),
field_three = (SELECT model_a.field_three FROM model_a WHERE model_a.id = model_b.model_a_id LIMIT 1);
解决方案
不幸的是,ORM 不支持分散多列的注释,我不知道它的功能请求。
如果你想坚持使用 ORM,你将不得不承受可能的性能损失(也许 PostgreSQL 足够聪明,只能使用一个;EXPLAIN
会告诉你)否则你将不得不切换到.raw
SQL。
推荐阅读
- pytest - pytest_report_teststatus 钩子在会话范围的拆卸固定装置之后执行
- c# - 如何使用c#找到3个点的最小x坐标
- pandas - 使用具有相同索引和列的两个数据框创建新数据框
- django - 如何使用 django 模型将“注释”数据添加到具有多个“值”的查询中?
- go - gorm beforeDelete 无法获取结构值
- c++ - 从二维数组创建 cv::Mat 图像
- java - 如何禁用按钮以打开谷歌地图 - Google API android studio java
- python - 使用 NaN 获得熊猫系列模式的最快方法
- javascript - 将 HTML5 表单输入添加到服务器端文本文件
- python - 在条件python上停止程序