我在 PostgreSQL 上有一个 Django JSONField,其中包含一个字典,我想使用 queryset.update() 来批量更新多个键的值。 I know how to do it for one value在 JSONField 中(通常对于多个字段):
from django.db.models import Func, Value, CharField, FloatField, F, IntegerField
class JSONBSet(Func):
"""
Update the value of a JSONField for a specific key.
"""
function = 'JSONB_SET'
arity = 4
output_field = CharField()
def __init__(self, field, path, value, create: bool = True):
path = Value('{{{0}}}'.format(','.join(path)))
create = Value(create)
super().__init__(field, path, value, create)
这似乎有效 - 根据我的其他问题存在一些差距 - 像这样:
# This example sets the 'nestedkey' to numeric 199.
queryset.update(inputs=JSONBSet('inputs', ['nestedkey_1'], Value("199"), False))
但是,如果我现在想在同一个 inputs
内更新第二个 nestedkey_2
,我显然不能像这样使用 inputs
参数两次:
queryset.update(inputs=JSONBSet(...'nestedkey_1'...), inputs=JSONBSet(...'nestedkey_2'...)
有办法做到这一点吗?
最佳答案
我终于明白了。 Postgres 有 jsonb 运算符“||”可以像这样与 Django 一起使用:
from django.db.models import Func
from django.db.models.functions import JSONObject
class JSONBUpdate(Func):
def __init__(self, field, update):
super().__init__(update)
self.template = "{} || %(expressions)s".format(field)
#
# Form a dict with the key-value pair we want to overwrite.
#
tmp = JSONObject(**{'inputs-0-value': Value("199999"), 'inputs-1-value': Value("123456")})
#
# Overwrite 'inputs-0-value' and 'inputs-1-value' using the dict.
#
queryset.update(inputs=JSONBUpdate('inputs', tmp))
简单!
FWIW,似乎其他数据库都有一个或多或少标准化的函数,其名称如 jsonb_update ,我怀疑它的作用类似于“||”。
关于python - 如何 Django ORM update() 嵌套在 JSONField 中的多个值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68620977/