我有一个mysql表,代表编辑文章及其元数据,如title,author和datecreated。
我有另一个表格,表示在不同时间点计算的那些文章的指标(例如视图计数)。每一行都是在特定时刻记录特定文章的这些指标。
我想检索度量表的所有行,其中度量标准行时间戳字段在相关文章的datecreated字段超过一小时后发生的两小时内。我想使用SQLalchemy执行此操作。
我当前的SQLalchemy查询如下所示:
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()
但是,这会导致以下错误:
Warning: (1292, u"Truncated incorrect DOUBLE value: '1970-01-01 05:30:00'")
在尝试在不同类型之间进行比较时,mySQL会在进行比较之前在内部将不同类型的数据转换为双精度数据。我相信这个错误在某种程度上是使用timedelta的结果,但我不确定我怎么能实现我想要做的事情。任何建议都非常欢迎。
答案 0 :(得分:2)
实际上,这比它看起来更难。如果你直接在MySQL中完成了这个,那就是你要写的:
SELECT ...
FROM ...
JOIN ...
WHERE tstamp BETWEEN DATE_ADD(created, INTERVAL 1 HOUR) AND DATE_ADD(created, INTERVAL 3 HOUR)
GROUP BY ...
您必须使用SQLAlchemy做同样的事情,因为m.Article.created
不是常量。
如果启用查询日志记录,您可以看到代码生成的MySQL查询,并且看到它与您的想法不符:
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)}
我设法找到了一种方法来做你想做的事,这是代码:
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')))