我有一个表,用于存储用户提交的任务,并带有时间戳。我想写一个查询,根据提交时间返回某些行(是这一天/周/月......)。
为了检查它是否在本周提交,我想使用date.isocalendar()[1]
功能。问题是,我的时间戳是datetime
s,所以我需要将它们转换为date
s。
使用func:
filter(func.date(Task.timestamp) == datetime.date(datetime.utcnow()))
工作正常。
但我需要date
对象的isocalendar()
方法,所以我试试
filter(func.date(Task.timestamp).isocalendar()[1]==datetime.date(datetime.utcnow()).isocalendar()[1])
并且它没有用,我得到AttributeError: Neither 'Function' object nor 'Comparator' object has an attribute 'isocalendar'
如果我做一个简单的查询并尝试datetime.date(task.timestamp).isocalendar()[1]
它可以正常工作。
如何在查询的过滤器中使用它?
答案 0 :(得分:1)
理解和调试sqlalchemy查询时的经验法则总是要考虑 - “它在SQL中的外观如何?”
isocalendar()
是一个python函数,sqlalchemy查询过滤器被编译为SQL。而且,isocalendar()
返回一个元组 - 虽然渲染元组比较可能是SQL,但它的价值更大。你应该比较标量并找到适合你的sql日期函数。
似乎你想要比较周数,所以这样的事情应该可以解决问题:
filter(func.week(Task.timestamp)==datetime.utcnow().isocalendar()[1])
答案 1 :(得分:0)
你能试试sqlalchemy.extract(func.date('year', Task.timestamp)) == ...
吗?
答案 2 :(得分:0)
您不能将纯Python函数与在SQL
后端执行的函数混合使用。从您的代码看,您似乎正在尝试过滤iso week
。一种方法是将数据库中的所有内容加载到内存中并在那里执行过滤。显然,在大多数情况下,它远没有效率。
另一种方法是使用SQL
函数,sqlalchemy
将为您调用。在MySQL
上看起来您需要的功能是weekofyear
,因此您的过滤器可能类似于以下内容:
_utcnow = datetime.utcnow().date()
_isoweek = _utcnow.isocalendar()[1]
q = db.session.query(...)
# ...
q = q.filter(db.func.weekofyear(Task.timestamp) == _isoweek)