django CASE 类型间隔和整数无法匹配



在Django中,我正在创建一个带有CASE和注释的查询集。它看起来像这样:

days_diff_calc = Case(
When(Q(sent_date__isnull=True),
then=None),
When(Q(received_date__isnull=True),
then=(timezone.now().date() - F('sent_date'))),
default=(F('received_date') - F('sent_date')),
output_field=DurationField()
)
Item.objects.all().annotate(
days_diff=days_diff_calc
)

它创建的查询的重要部分如下所示:

CASE 
WHEN "item"."sent_date" IS NULL THEN NULL 
WHEN "item"."received_date" IS NULL THEN ('2019-11-26' - "item"."sent_date") 
ELSE (interval '1 day'* ("item"."received_date" - "item"."sent_date"))
END AS "days_diff"  

在 Postgres 中运行时,出现此错误:

CASE types interval and integer cannot be matched
LINE 3: ...item"."received_date" IS NULL THEN ('2019-11-2...
^

似乎出于某种原因,Django ORM 在 ELSE 之后添加了interval 1 day *,但在第二个 WHEN 之后没有这样做,我认为这就是此错误的原因。我不明白 - 为什么它只添加到一个地方而不是另一个地方,如果我想把它添加到另一个地方(第二个时间( - 我会这样做吗?

编辑:

姜戈 2.1.5 版本, psycopg2 版本 2.6.2, Postgresql 9.6

所有"日期"字段均为models.DateField(null=True, blank=True)类型

也尝试使用表达式包装器并得到相同的结果:

days_diff_calc = Case(
When(Q(sent_date__isnull=True),
then=None),
When(Q(received_date__isnull=True),
then=ExpressionWrapper(timezone.now().date() - F('sent_date'),
output_field=DurationField())),
default=ExpressionWrapper(F('received_date') - F('sent_date'),
output_field=DurationField()),
)

我对这个问题的理解不是很深入,但我至少可以提供以下解决方法,这似乎可以解决问题:

days_diff_calc = Case(
When(Q(sent_date__isnull=True), then=None),
When(Q(received_date__isnull=True),
then=timedelta(days=1)*(timezone.now().date() - F('sent_date'))),
default=(F('received_date') - F('sent_date')),
output_field=DurationField()
)

WRT 为什么在您的情况下没有发生单位转换,我不完全清楚。 在 Postgres 中,减去日期会产生一个 int,这就是为什么需要将其转换为持续时间的原因。 我猜也许在这一行 expressions.py 日期文字不被识别为与DateField相同的类型。 如果您在sent_dateDateTimeField的模型上运行相同的代码,它似乎工作正常,但在这种情况下,您不需要额外的间隔表达式。

相关内容

  • 没有找到相关文章

最新更新