如何在JSONField的`update`中使用Django F()表达式

4

我需要在我的Postgres数据库中更新大约1200万条记录(所以我需要高效地完成它)。

我正在使用Django。

我必须更新一个jsonfield列(extra_info),并使用同一模型中不同的列(related_type_id,它是一个整数)的值。

尝试使用update命令完成。这似乎是最有效的方法。

例如:

Person.objects.all().update(extra_info={
  "type": "Human",
  "id": F('related_type_id')
})

这个错误是: "类型为F的对象不可被JSON序列化"。 我认为,F()应该会返回该列的值(应该是一个整数),而该值应该是可序列化的。 这可以实现吗?还是我尝试了错误的方法? 我不想用for循环迭代每个记录并使用save()更新,因为这将需要太长时间。有太多的记录。
1个回答

4
Django数据库函数JSONObject应该可以使用,它可以从键值对返回有效的JSON对象,并且可以传递F对象。
from django.db.models import F, Value
from django.db.models.functions import JSONObject

Person.objects.all().update(extra_info=JSONObject(
  type=Value('Human'),
  id=F('related_type_id')
))

哇,不错,这似乎对 F() 部分有效!有任何想法为什么我会得到“无法将关键字“Human”解析为字段。选择是:<这里列出模式中可用的列>”这似乎是一个奇怪的错误,为什么它把“Human”当作关键字处理呢?我还尝试将 type 更改为 custom_type,但是出现了相同的错误(我想看看是否保留了“type”,但没有任何区别)。 - sco
@sco 使用 Value 应该可以解决问题,更新链接:https://docs.djangoproject.com/en/4.0/ref/models/expressions/#value-expressions。如果你只传递一个字符串,它似乎会使用列的值,你可能不需要使用 F 对象,只需使用字符串 'related_type_id' 即可。 - Iain Shelvington

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接