【问题标题】:Django query annotation without timezone没有时区的 Django 查询注释
【发布时间】:2019-11-09 00:25:25
【问题描述】:

我正在尝试使用 Django 的查询对象编写以下查询:

all_proposals2 = Proposal.objects.raw(
"select *, vote_score/extract('epoch' from age(created)) as display_rank from proposals_proposal")

这是我想出的:

all_proposals = Proposal.objects.annotate(
    display_rank=F('vote_score') / Extract(Func(F('created'), function='AGE'), 'epoch'),
)

但它会生成这个查询:

SELECT
   "proposals_proposal"."id",
   ...
   ("proposals_proposal"."vote_score" / 
      EXTRACT('epoch' FROM AGE("proposals_proposal"."created") AT TIME ZONE 'America/Los_Angeles')) AS "display_rank" 
FROM
   "proposals_proposal" 
ORDER BY
   "proposals_proposal"."created" ASC

这不是一个有效的查询。 Postgres 给出这个错误:

HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

但它非常接近正确,除了它在AGE() 函数调用上附加了额外的AT TIME ZONE 'America/Los_Angeles'。如何更改查询以使其没有此时区规范?

【问题讨论】:

  • 你试过USE_TZ = False吗?
  • 设置 USE_TZ=False 确实修复了查询,但我希望时区位于所有其他相关的地方。在此查询中,它将时区应用于不应有时区的间隔。

标签: django postgresql timezone annotate


【解决方案1】:

在查看了应用此时区规则的 source code for the Extract function 之后,我意识到我必须使用通用的 Func 来编写此 Extract 调用。

    all_proposals = Proposal.objects.annotate(
        display_rank=ExpressionWrapper(F('vote_score') / Func(
            Func(F('created'), function='AGE'),
            function='EXTRACT',
            template='%(function)s(epoch from %(expressions)s)',
        ), output_field=FloatField()),
    )

这会绕过任何自动时区规范。

【讨论】:

    猜你喜欢
    • 2020-05-14
    • 1970-01-01
    • 2020-02-13
    • 1970-01-01
    • 2020-01-18
    • 2018-04-16
    • 2015-11-15
    • 2013-02-28
    • 1970-01-01
    相关资源
    最近更新 更多