Проблема с арифметическими выражениями с годами в запросах - PullRequest
1 голос
/ 20 мая 2019

Похоже, что django не создает правильный запрос MySQL при простой арифметике с ExtractYear ().

У меня есть модель с двумя полями данных:

class Event(models.Model):
    start_date = models.DateField()
    finish_date = models.DateField()

ЕслиЯ хочу найти все строки так, чтобы годы start_date и finish_date были равны, я могу сделать это так:

from django.db.models import F
from django.db.models.functions import ExtractYear
>>> print Event.objects.annotate(year=ExtractYear(F('start_date'))).filter(finish_date__year=F('year')).only('pk').query
SELECT `event`.`id`, EXTRACT(YEAR FROM `event`.`start_date`) AS `year` FROM `event` WHERE EXTRACT(YEAR FROM `event`.`finish_date`) = (EXTRACT(YEAR FROM `event`.`start_date`))

Но если я хочу найти события, которые начинаются и заканчиваются в последующие годы, я пытаюсьследующий фильтр, и он дает мне неправильный запрос MySQL:

>>> print Event.objects.annotate(year=ExtractYear(F('start_date'))).filter(finish_date__year=F('year')+1).only('pk').query
SELECT `event`.`id`, EXTRACT(YEAR FROM `event`.`start_date`) AS `year` FROM `event` WHERE `event`.`finish_date` BETWEEN 0001-01-01 AND 0001-12-31

Я пытался заменить F('year')+1 на F('year')+Value(1), но это не помогло.

  1. Я где-то ошибаюсь или это похоже на ошибку в django?

  2. Буду также признателен, если вы увидите какие-либо другие способы сделать то же самое!

Ответы [ 2 ]

1 голос
/ 20 мая 2019

Запрос кажется законным.

Однако в моем случае работал альтернативный запрос:

Event.objects.annotate(s_year=ExtractYear(F('start_date')), f_year=ExtractYear(F('finish_date')), diff=F("f_year")-F("s_year")).filter(diff=1).only('pk')

Просто аннотировали start_date, finish_date и diff.

0 голосов
/ 21 мая 2019

Вот что наконец сработало:

Event.objects.annotate(diff=ExpressionWrapper(ExtractYear(F('finish_date'))-ExtractYear(F('start_date')), output_field=IntegerField())).filter(diff=1).only('pk').query

Похоже, в django есть ошибка. Я добавил это к https://code.djangoproject.com/ticket/30494.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...