How to filter datetime field +/- datetime using SQLalchemy
我有一个mysql表,表示编辑文章及其元数据,如标题、作者和日期创建。
我有另一个表,表示在不同时间点计算的关于这些项目的度量(例如视图计数)。每一行都是特定文章在特定时间点的这些指标的记录。
我想检索度量表的所有行,其中度量行时间戳字段在相关文章的datecreated字段过去一小时后发生的两小时内。我想用sqlacalchemy来做这个。
我当前的sqlAlchemy查询如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import sqlalchemy as sa import models as m s = session() q = (s.query(m.Article.fb_shares, func.avg(m.ArticlesMetric.views)), .join(m.ArticlesMetric) .filter(sa.between(m.ArticlesMetric.tstamp, m.Article.created + timedelta(hours=1), m.Article.created + timedelta(hours=3)) ) .group_by(m.Article.id)) result = q.all() s.close() |
但是,这会导致以下错误:
1 | Warning: (1292, u"Truncated incorrect DOUBLE value: '1970-01-01 05:30:00'") |
当尝试比较不同类型时,MySQL在内部将不同类型的数据强制转换为两倍数据,然后再进行比较。我相信这个错误在某种程度上是使用TimeDelta的结果,但我不确定我还能如何实现我正在尝试的目标。任何建议都非常欢迎。
实际上,这比看起来更难。如果您在MySQL中直接这样做,那么您应该这样写:
1 2 3 4 5 | SELECT ... FROM ... JOIN ... WHERE tstamp BETWEEN DATE_ADD(created, INTERVAL 1 HOUR) AND DATE_ADD(created, INTERVAL 3 HOUR) GROUP BY ... |
对于sqlAlchemy,你必须或多或少地做同样的事情,仅仅是因为
如果启用查询日志记录,则可以看到代码生成的MySQL查询,并看到它与您的想法不符:
1 2 3 4 | INFO:sqlalchemy.engine.base.Engine:SELECT test.id AS test_id, test.dt AS test_dt, test.tp AS test_tp FROM test WHERE test.tp BETWEEN test.dt + %(dt_1)s AND test.dt + %(dt_2)s INFO:sqlalchemy.engine.base.Engine:{'dt_1': datetime.datetime(1970, 1, 1, 1, 0), 'dt_2': datetime.datetime(1970, 1, 1, 3, 0)} |
我设法找到了一种做你想做的事情的方法,代码如下:
1 2 3 4 5 6 7 | from sqlalchemy.sql import func from sqlalchemy.sql.expression import text ... filter(sa.between(m.ArticlesMetric.tstamp, func.date_add(m.Article.created, text('INTERVAL 1 HOUR')), func.date_add(m.Article.created, text('INTERVAL 3 HOUR'))) |