在sqlalchemy中的datetime字段中过滤时间范围

时间:2013-11-27 23:03:01

标签: python sqlalchemy

当我在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

任何帮助都将不胜感激。

2 个答案:

答案 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