Аннотация запроса Django без часового пояса - PullRequest
0 голосов
/ 09 ноября 2019

Я пытаюсь написать следующий запрос, используя объекты запросов 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.

Но она очень близка к исправлению, за исключением того, что к ней добавлен дополнительный AT TIME ZONE 'America/Los_Angeles', добавленный к вызову функции AGE(). Как я могу изменить запрос, чтобы у него не было этой спецификации часового пояса?

1 Ответ

0 голосов
/ 09 ноября 2019

Просмотрев исходный код для функции Extract , которая применяет это правило часового пояса, я понял, что мне придется написать этот вызов Extract с общим Func взамен.

    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()),
    )

Это обходит любую автоматическую спецификацию часового пояса.

...