Sch*_*itz 6 python django postgresql datetime
我已经搜索了很长时间,并且知道关于 sof 的几个答案,但是即使我的问题非常简单,但没有一个解决方案在我结束时有效:
我需要什么(使用 postgres + django 1.10):我在日期时间字段中有很多行有很多重复的日期(=天)。我想要一个包含每个日期/天的行/对象的查询集。
fk | col1 | colX | created (type: datetime)
----------------------------------------------
1 | info | info | 2016-09-03 08:25:52.142617+00:00 <- get it (time does not matter)
1 | info | info | 2016-09-03 16:26:52.142617+00:00
2 | info | info | 2016-09-03 11:25:52.142617+00:00
1 | info | info | 2016-09-14 16:26:52.142617+00:00 <- get it (time does not matter)
3 | info | info | 2016-09-14 11:25:52.142617+00:00
1 | info | info | 2016-09-25 23:25:52.142617+00:00 <- get it (time does not matter)
1 | info | info | 2016-09-25 16:26:52.142617+00:00
1 | info | info | 2016-09-25 11:25:52.142617+00:00
2 | info | info | 2016-09-25 14:27:52.142617+00:00
2 | info | info | 2016-09-25 16:26:52.142617+00:00
3 | info | info | 2016-09-25 11:25:52.142617+00:00
etc.
Run Code Online (Sandbox Code Playgroud)
什么是最好的(性能 + pythionic/django)方式来做到这一点。我的模型/表将有很多行(> 百万)。
编辑 1
结果必须首先通过 fk(例如 WHERE fk = 1)过滤。
我已经尝试过最明显的事情,例如
MyModel.objects.filter(fk=1).order_by('created__date').di??stinct('created__dat??e')
Run Code Online (Sandbox Code Playgroud)
但出现以下错误:
django.core.exceptions.FieldError:无法将关键字“日期”解析为字段。不允许在“创建”时加入。
...与 all() 和通过类 Meta 进行相应排序而不是查询方法 order_by() 的相同错误...
在这种特定情况下,有人可能更了解这个错误吗?
考虑到当前的 Django 实现,这似乎是不可能的,因为这将涉及使用高级数据库后端函数(如Postgres 窗口函数)。
您所拥有的最接近的是使用聚合:
MyModel.objects.annotate(
created_date=TruncDay('created')
).values('created_date').annotate(id=Min('id'))
Run Code Online (Sandbox Code Playgroud)
这将聚合相似的日期,并选取最小的 ID。
[{'created_date': datetime.date(2017, 3, 16), 'id': 146},
{'created_date': datetime.date(2017, 3, 28), 'id': 188},
{'created_date': datetime.date(2017, 3, 24), 'id': 178},
{'created_date': datetime.date(2017, 3, 23), 'id': 171},
{'created_date': datetime.date(2017, 3, 22), 'id': 157}] ...
Run Code Online (Sandbox Code Playgroud)
如果您需要整个对象,您可以将其与一个.values_list()和另一个查询集链接起来,这将产生一个子查询:
MyModel.objects.filter(
id__in=MyModel.objects.annotate(
created_date=TruncDay('created')
).values('created_date').annotate(id=Min('id')).values_list(
'id', flat=True
)
)
Run Code Online (Sandbox Code Playgroud)
仅供参考,这会导致以下查询
SELECT
"myapp_mymodel"."id",
"myapp_mymodel"."created",
"myapp_mymodel"."col1",
"myapp_mymodel"."colX"
FROM "myapp_mymodel"
WHERE "myapp_mymodel"."id" IN (
SELECT MIN(U0."id") AS "id"
FROM "myapp_mymodel" U0
GROUP BY DATE(U0."created")
)
Run Code Online (Sandbox Code Playgroud)
Mat*_*Dfr -2
您可以使用查询集通过创建值的不同来从表中获取结果,因为您使用的是 postgresql。
也许像这样的查询应该可以完成工作:
MyModel.objects.all().distinct('created__date')
Run Code Online (Sandbox Code Playgroud)
我也向您推荐 django 的查询集文档:https://docs.djangoproject.com/fr/1.10/ref/models/querysets/#distinct