在SQLAlchemy中按特定格式按日期分组
我有一个叫做 logs 的表,这个表里面有一个日期时间的字段。
我想根据特定的日期格式来选择日期和行数的统计。
我该如何使用 SQLAlchemy 来实现这个呢?
3 个回答
0
我对SQLAlchemy不太了解,所以可能说得不太准确。不过,我觉得你只需要:
SELECT date_formatter(datetime_field, "format-specification") AS dt_field, COUNT(*)
FROM logs
GROUP BY date_formatter(datetime_field, "format-specification")
ORDER BY 1;
好吧,也许你不需要ORDER BY,可能重新指定一下日期表达式会更好。还有其他的选择,比如:
SELECT dt_field, COUNT(*)
FROM (SELECT date_formatter(datetime_field, "format-specification") AS dt_field
FROM logs) AS necessary
GROUP BY dt_field
ORDER BY dt_field;
等等。总的来说,你就是把日期时间字段格式化一下,然后再对格式化后的值进行分组等操作。
1
如果你只是根据未格式化的日期时间列进行分组,计数的结果会一样吗?如果是这样的话,你可以直接运行这个查询,然后再用Python日期的strftime()方法来处理。也就是说:
query = select([logs.c.datetime, func.count(logs.c.datetime)]).group_by(logs.c.datetime)
results = session.execute(query).fetchall()
results = [(t[0].strftime("..."), t[1]) for t in results]
5
我不知道有没有一个通用的 SQLAlchemy 解决方案。大多数数据库都支持某种形式的日期格式化,通常是通过一些函数来实现的。SQLAlchemy 允许我们通过 sqlalchemy.sql.func 来调用这些函数。比如说,如果我在使用 SQLAlchemy 连接一个 Postgres 数据库,并且有一个表 my_table(foo varchar(30), when timestamp),我可能会这样做:
my_table = metadata.tables['my_table']
foo = my_table.c['foo']
the_date = func.date_trunc('month', my_table.c['when'])
stmt = select(foo, the_date).group_by(the_date)
engine.execute(stmt)
这样可以按月份来分组日期。不过要注意,在这个例子中,date_trunc() 是 Postgres 的一个日期时间函数。其他数据库可能会有所不同。你没有提到具体使用的数据库。如果有一种不依赖于数据库的方法,我还没找到过。在我的情况下,我在生产环境和测试环境中都使用 Postgres,而在单元测试中使用 SQLite,因此我不得不在单元测试中使用 SQLite 的用户定义函数来模拟 Postgres 的日期时间函数。