Django 相当于 SQL REPLACE
是否有针对此 SQL 的 Django ORM 最佳实践:
REPLACE app_model SET field_1 = 'some val', field_2 = 'some val';
假设:field_1 或 field_2 将有一个唯一的键(或者在我的情况下两者都有),否则这将始终评估为 INSERT。
编辑:
我现在最好的个人答案是这样的,但它是 2-3 个查询,其中 1 个应该是可能的:
from django.core.exceptions import ValidationError
try:
Model(field_1='some val',field_2='some val').validate_unique()
Model(field_1='some val',field_2='some val',extra_field='some val').save()
except ValidationError:
Model.objects.filter(field_1='some val',field_2='some val').update(extra_field='some val')
Is there a Django ORM best practice for this SQL:
REPLACE app_model SET field_1 = 'some val', field_2 = 'some val';
Assumption: field_1 or field_2 would have a unique key on them (or in my case on both), otherwise this would always evaluate to an INSERT.
Edit:
My best personal answer right now is this, but it's 2-3 queries where 1 should be possible:
from django.core.exceptions import ValidationError
try:
Model(field_1='some val',field_2='some val').validate_unique()
Model(field_1='some val',field_2='some val',extra_field='some val').save()
except ValidationError:
Model.objects.filter(field_1='some val',field_2='some val').update(extra_field='some val')
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您说您想要
REPLACE
,我相信这应该在插入之前删除任何现有行,但您的示例表明您想要更像UPSERT
。AFAIK,django 不支持
REPLACE
(或 sqlite 的INSERT OR REPLACE
或UPSERT
)。但是您的代码可以合并:这当然假设
field_1
、field_2
或两者都是唯一的(正如您所说)。它仍然是两个查询(用于
get_or_create
的SELECT
和用于save
INSERT 或UPDATE
code>),但在类似 UPSERT 的解决方案出现之前(而且可能不会持续很长一段时间),这可能是您能做的最好的事情。You say you want
REPLACE
, which I believe is supposed to delete any existing rows before inserting, but your example indicates you want something more likeUPSERT
.AFAIK, django doesn't support
REPLACE
(or sqlite'sINSERT OR REPLACE
, orUPSERT
). But your code could be consolidated:This of course assumes that either
field_1
,field_2
, or both are unique (as you've said).It's still two queries (a
SELECT
forget_or_create
, and anINSERT
orUPDATE
forsave
), but until anUPSERT
-like solution comes along (and it may not for a long, long time), it may be the best you can do.从 Django 1.7 开始,您可以使用
update_or_create< /code>
方法:
Since Django 1.7 you can use
update_or_create
method:我认为下面的方法更有效。
如果该行尚未创建且需要更新,这只会更新 extra_field。
I think the following is more efficient.
This will only update the extra_field if the row was not created and needs to be updated.