【问题标题】:How to Django ORM update() multiple values nested inside a JSONField?如何 Django ORM update() 嵌套在 JSONField 中的多个值?
【发布时间】:2021-10-07 18:29:51
【问题描述】:

我在 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'...)

有没有办法做到这一点?

【问题讨论】:

  • 这能回答你的问题吗? How to 'bulk update' with Django?
  • @AnkitTiwari 否。通常, update() 使用关键字参数调用,其中每个关键字命名一个要更新的单独字段。这里的问题是必须使用相同的参数名称。

标签: python django orm django-jsonfield


【解决方案1】:

我终于明白了。 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,我怀疑它的功能类似于“||”。

【讨论】:

    猜你喜欢
    • 2017-06-28
    • 2017-04-12
    • 1970-01-01
    • 2021-07-22
    • 1970-01-01
    • 2019-07-28
    • 1970-01-01
    • 2018-01-18
    • 1970-01-01
    相关资源
    最近更新 更多