【问题标题】:Query date on datetime stored within jsonfield in Postgres through Django?通过Django查询存储在Postgres的jsonfield中的日期时间?
【发布时间】:2021-08-12 11:17:11
【问题描述】:

我有一个 Postgres 表,其中有一个 jsonb 列,其中包含 ISO 格式的 UTC 时间戳数据,如下所示:

{
    "time": "2021-04-13T20:14:56Z"
}

此表的 Django 模型如下所示:

class DateModel(models.Model):
    values = models.JSONField(default=dict)

我需要在表中查询所有具有特定日期时间戳的记录(忽略时间)

我正在寻找类似于以下的解决方案:

DateModel.objects.filter(values__time__date='2021-04-13')

我发现的另一个解决方案是查询日期大于前一天且小于下一天的记录。这可行,但我正在寻找一种通过单个查询来完成它的方法,这样代码会更简洁。

有什么建议吗?

【问题讨论】:

    标签: python-3.x django django-models jsonb


    【解决方案1】:

    您需要在查询集上执行几个注释来提取时间字段并将其转换为日期时间。

    首先你需要使用django.contrib.postgres.fields.jsonb.KeyTextTransform提取时间字符串

    from django.contrib.postgres.fields.jsonb import KeyTextTransform
    
    query = DateModel.objects.annotate(time_str=KeyTextTransform('time', 'values'))
    

    然后你需要使用Cast将该字符串转换为日期时间

    from django.db.models.functions import Cast
    from django.db.models import DateTimeField
    
    query = query.annotate(time=Cast('time_str', output_field=DateTimeField()))
    

    然后您可以按该注释进行过滤

    query = query.filter(time__date='2021-04-13')
    

    【讨论】:

    • 感谢您的回答。我玩了一下,结果证明我们可以不使用 KeyTextTransform 来做到这一点。我们只需要对 Casts 做:query.annotate( time_str=time=Cast('values__time', output_field=TextField())) ).annotate(time=Cast('time_str', output_field=DateTimeField()))
    猜你喜欢
    • 2018-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-30
    • 2021-04-03
    • 2018-10-02
    • 2019-03-22
    • 2012-10-14
    相关资源
    最近更新 更多