在嵌套的 Django JSONField 中搜索(通过 Django ORM 或原始 sql)

Search within nested Django JSONField (either via Django ORM or raw sql)

编辑: 在下面添加了解决方案。没有人能够推荐原生的 Postgres,一次搜索和替换,所以我不得不在 Python 中解析日志,然后进行更新。

版本Django==1.10.3Postgres 9.6

有没有办法在嵌套的 Django JSONField(由 Postgres jsonb 支持)中搜索特定的 key/value 状态?理想情况下,这将是原生 Django,但如果需要,我可以分解为原始 sql。

例如在以下数据中搜索一个或多个 {"status":"running}

{"subtask1": {"status":"running"},
 "subtask2": {"status":"complete"}}

背景:

我正在使用 JSONField 来记录长期 运行 子任务的当前状态。每个子任务通过服务器上的 nativePostgres jsonb_set() 操作有选择地更新其 json 字段的元素。

在每个子任务之后,我想查询 log 字段以查看该子任务是否是最后一个完成的。如果全部完成(即在嵌套的 json 树中没有出现 {"status":"running"}),那么我将更新 Django RunningTask 实例的主要 .complete 字段。

示例和简化模型:

class LongRunningTask(models.model):
    id = models.AutoField(primary_key=True)
    complete = models.BooleanField(default=False)
    log = JSONField(null=True, blank=True, default=dict)

log 字段的示例数据:

{"subtask1": {"status":"running"},
 "subtask2": {"status":"complete"}}

在此先感谢您的指点。

注:

我试过 Django 的内置 contains 运算符,但是这找不到值,因为它们嵌套在下一层。我对 values operator 的前景感到兴奋,但根据我的测试,它没有在 JSONField 上实现(仅 HStoreField)。

解法:

找不到原生的 Postgres 一次性搜索和替换调用,所以我最终在每个子任务完成后解析 Python 中的日志,以确定它是否是最后一个。希望能及时找到更好的解决办法

_current_log = LongRunningTask.objects.get(pk=current_task.id).log
_statuses = [True if _current_log[i]["status"] == "complete"
             else False
             for i in _current_log]
if all(_statuses):
    LongRunningTask.objects.filter(pk=adhoc_task.id).update(complete=True)

试试这个方法:

import json

all_completed=True
json_dict=json.loads(json_log)
for key,value in json_dict.items():
   if json_dict[key]['status']!='complete':
       all_completed=False
       break

这只是一个提示。您可以根据自己的要求进行更改。

试试这个:-

LongRunningTask.objects.filter(log__values__contains={"status":"running"})