【问题标题】:How do I write a Django query and include a PostGres function (current_time) in my WHERE clause?如何编写 Django 查询并在 WHERE 子句中包含 PostGres 函数 (current_time)?
【发布时间】:2019-08-16 00:10:59
【问题描述】:

我正在使用 Django、Python 3.7 和 PostGres 9.5。我想在 Django 中编写以下 WHERE 子句...

WHERE date_part('hour', current_time) = s.hour ...

所以在阅读其他一些文档时,我被引导相信我需要在运行查询之前编写一个“Func”创建一个注释......

qset = ArticleStat.objects.annotate(
    hour_of_day=Func(
        'current_time',
        Value('hour'),
        function='date_part',
    )
).filter(hour_of_day=F("article__website__stats_per_hour__hour"))

但是,这会导致

Cannot resolve keyword 'current_time' into field. Choices are: article, article_id, elapsed_time_in_seconds, id, score

错误。似乎 Django 正在尝试将“current_time”视为我表中的一列,但我真的希望它被视为 PostGres 函数。我该怎么做?

【问题讨论】:

    标签: python django python-3.x postgresql func


    【解决方案1】:

    更新 2:阅读您使用带注释的 hour_of_day 的过滤器子句,只需将子句转过来就可以轻松很多,除非我忽略了某些内容:

    hour = datetime.datetime.now().hour
    qset = ArticleStat.objects.filter(article__website__stats_per_hour__hour=hour)
    

    更新:比下面的双注释黑客更容易的是在 Python 中获取当前时间(每个查询一次,而不是每行一次)并将其传递给函数。您可能需要确保时区匹配。

    import datetime
    from django.db.models import DateTimeField
    from django.db.models.expressions import Func, Value
    
    current_time = datetime.datetime.now()
    qset = Session.objects.annotate(
        hour_of_day=Func(
            Value('hour'),
            Value(current_time, output_field=DateTimeField()),
            function='date_part',
        )
    )
    

    一个简单的技巧是使用两个注释来避免将一个数据库函数嵌套在另一个中(如果你足够认真的话,你可以使用从Func 子类化的自定义函数来做到这一点):

    from django.db.models import DateTimeField
    from django.db.models.expressions import Func, Value
    
    qset = MyModel.objects.annotate(
        current_time=Func(
            Value(0),
            function='current_time',
            output_field=DateTimeField()
        )).annotate(
        hour_of_day=Func(
            Value('hour'),
            F('current_time'),
            function='date_part',
        )
    )
    

    【讨论】:

      猜你喜欢
      • 2015-10-30
      • 2019-08-01
      • 1970-01-01
      • 2022-08-08
      • 1970-01-01
      • 2019-05-07
      • 1970-01-01
      • 1970-01-01
      • 2019-09-02
      相关资源
      最近更新 更多