Я пытаюсь написать запрос, который извлекает все подписки, владельцы которых должны быть уведомлены о его истечении.
Я бы хотел исключить уже подписанные подписки и подписки, для которых доступна более новая подписка.
Запрос следующий:
Subscription.objects.filter(
end_date__gte=timezone.now(),
end_date__lte=timezone.now() + timedelta(days=14),
).exclude(
Q(notifications__type=Notification.AUTORENEWAL_IN_14) | Q(device__subscriptions__start_date__gt=F('start_date'))
)
Без части | Q(device__subscriptions__start_date__gt=F('start_date')
запрос работает отлично. При этом django (postgres) вызывает следующую ошибку:
django.db.utils.ProgrammingError: missing FROM-clause entry for table "u1"
LINE 1: ...ption" U0 INNER JOIN "orders_subscription" U2 ON (U1."id" = ...
Я проверил sql, и он кажется неправильным:
SELECT "orders_subscription"."id",
"orders_subscription"."months",
"orders_subscription"."end_date",
"orders_subscription"."start_date",
"orders_subscription"."order_id",
"orders_subscription"."device_id",
FROM "orders_subscription"
WHERE ("orders_subscription"."churned" = false
AND "orders_subscription"."end_date" >= '2019-04-05T13:27:39.808393+00:00'::timestamptz
AND "orders_subscription"."end_date" <= '2019-04-19T13:27:39.808412+00:00'::timestamptz
AND NOT (("orders_subscription"."id" IN
(SELECT U1."subscription_id"
FROM "notifications_notification" U1
WHERE (U1."type" = 'AUTORENEWAL_IN_2W'
AND U1."subscription_id" IS NOT NULL))
OR ("orders_subscription"."device_id" IN
(SELECT U2."device_id"
FROM "orders_subscription" U0
INNER JOIN "orders_subscription" U2 ON (U1."id" = U2."device_id")
WHERE (U2."start_date" > (U0."start_date")
AND U2."device_id" IS NOT NULL))
AND "orders_subscription"."device_id" IS NOT NULL)))) LIMIT 21
Execution time: 0.030680s [Database: default]
Это та часть, которая вызывает проблему:
INNER JOIN "orders_subscription" U2 ON (U1."id" = U2."device_id")
WHERE (U2."start_date" > (U0."start_date")
AND U2."device_id" IS NOT NULL))
U1 нигде не определен (это локально в другом предложении, но это не имеет значения.
Реляционная модель довольно проста: устройство может иметь много подписок, подписка может иметь много (разных) уведомлений.
class Subscription(models.Model):
end_date = models.DateTimeField(null=True, blank=True)
start_date = models.DateTimeField(null=True, blank=True)
device = models.ForeignKey(Device, on_delete=models.SET_NULL, null=True, blank=True, related_name="subscriptions")
# Other non significatn fields
class Device(models.Model):
# No relational fields
class Notification(models.Model):
subscription = models.ForeignKey('orders.Subscription', related_name="notifications", null=True, blank=True, on_delete=models.SET_NULL)
# Other non significatn fields
Итак, мой вопрос: мой запрос неправильный или это ошибка в генераторе запросов Django ORM?