当我在sqlalchemy中进行时间范围过滤时,我遇到了一个奇怪的问题。 Event表中有一个名为startDate的datetime列。我正在编写查询以返回所有开始时间在下午6点到晚上11:59之间的事件(无论哪个日期都无关紧要)。
我有以下代码,
from sqlalchemy import and_, Date, Time, cast
import datetime
startingTime = datetime.time(18, 0, 0)
endingTime = datetime.time(23, 59, 59)
如果我跑,
results = session.query(Event).filter(and_(cast(Event.startDate, Time)>=startingTime, cast(Event.startDate, Time)<=endingTime).all()
我没有结果(确定此范围内有事件)。
但如果我跑,
results = session.query(Event).filter(cast(Event.startDate, Time)>=endingTime).all()
它返回表中的所有行。
如果按日期过滤,
results = session.query(Event).filter(and_(cast(Event.startDate, Date)>=one_date, cast(Event.startDate, Date)<=another_date).all()
结果是对的!
假设Event_A的startDate是2013-11-27T19:30:00,
result = session.query(cast(Event.startDate, Time)).filter(Event.eventName=='Event_A').one()[0]
result >= startingTime ----> returns True
result <= endingTime ----> returns True
任何帮助都将不胜感激。
答案 0 :(得分:1)
实际上我猜是因为我使用的是sql server 2005,而且只有sql server 2008之后的版本才支持DATE和TIME对象。
我找到了一种使用func.convert完成此任务的替代方法:
session.query(TableName).filter(func.convert(func.VARCHAR(8), TableName.datetimefield, 8) >= datetime.time(0,0)).all()
答案 1 :(得分:0)
我无法复制这种行为。
进行调试,按步骤执行此操作:
session.query(TableName).filter(cast(TableName.some_datetimefield, Time) > '00:00:00').all()
# > all
session.query(TableName).filter(cast(TableName.some_datetimefield, Time) > '23:59:59').all()
# > []
session.query(TableName).filter(cast(TableName.some_datetimefield, Time) < '23:59:59').all()
# > all
session.query(TableName).filter(cast(TableName.some_datetimefield, Time) > datetime.time(0,0)).all()
# > all
session.query(TableName).filter(cast(TableName.some_datetimefield, Time) > datetime.time(23,59,59)).all()
# > []
session.query(TableName).filter(cast(TableName.some_datetimefield, Time) < datetime.time(23,59,59)).all()
# > all
session.query(TableName).filter(cast(TableName.some_datetimefield, Time) < datetime.time(23,59,59)).filter(cast(TableName.some_datetimefield, Time) > datetime.time(0,0)).all()
# > all
session.query(TableName).filter(and_(cast(TableName.some_datetimefield, Time) < datetime.time(23,59,59), cast(TableName.some_datetimefield, Time) > datetime.time(0,0)).all()
# > all