【发布时间】:2017-06-28 21:14:48
【问题描述】:
编辑:在下面添加了解决方案。没有人能够推荐原生 Postgres,一键搜索和替换,所以我不得不在 Python 中解析日志,然后进行更新。
版本:Django==1.10.3 和 Postgres 9.6
有没有办法在嵌套的 Django JSONField(由 Postgres jsonb 支持)中搜索特定的键/值状态?理想情况下,这将是一个原生 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)
【问题讨论】:
-
必须有unque key,不能为“subtask1”做reference,“subtask2”最好改成“subtask”。
-
嗨@PiyushS.Wanare - 这是子任务的唯一标识符,所以不能相同。
标签: python json django postgresql jsonb