在嵌套的 Django JSONField 中搜索(通过 Django ORM 或原始 sql)
Search within nested Django JSONField (either via Django ORM or raw sql)
编辑: 在下面添加了解决方案。没有人能够推荐原生的 Postgres,一次搜索和替换,所以我不得不在 Python 中解析日志,然后进行更新。
版本:Django==1.10.3
和Postgres 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"})
编辑: 在下面添加了解决方案。没有人能够推荐原生的 Postgres,一次搜索和替换,所以我不得不在 Python 中解析日志,然后进行更新。
版本:Django==1.10.3
和Postgres 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"})