Python Sqlalchemy:按月份的日期差筛选

4
我正在尝试将以下内容翻译为sqlalchemy:
SELECT COUNT(TableA.id) AS 'number_of_staff' 
FROM   TableA 
WHERE  datediff(month, TableA.Date, getDate()) >= 0
       AND lookup_TableB = '4'
       AND (TableA.End_Date IS NULL OR TableA.End_Date = '')

到目前为止,我已经:

get_tablea_number = self.db_session.query(func.count(TableA.id)).\
        filter(TableA.lookup_TableB == property_id, 
               todays_date.month - extract('month',  TableA.date) >= 0,
               or_(TableA.end_date == None,
                   TableA.end_date == '')).scalar()

然而,它输出与上面的SQL查询不同的值,我认为这是由于 todays_date.month - extract('month', TableA.date) >= 0 导致的(其中 todays_date.month 只是一个日期时间对象)。


你使用哪个数据库管理系统? - jarlh
1个回答

14

todays_date.month - extract('month', TableA.date) >= 0如果“今天”和TableA.date之间的差距超过一年,例如2016-04和2015-10,则可能不会按照您的意愿执行(类似的python代码):

In [8]: today = date.today()  # datetime.date(2016, 4, 12)

In [9]: a_date = date(2015,10,10)

In [10]: today.month - a_date.month
Out[10]: -6

另一方面,SQL Server的datediff函数所做的是:

返回指定日期部分之间跨越的特定日期边界的计数(有符号整数),从指定的开始日期到结束日期。

2016-04和2015-10之间有6个月,因此这将是正确的结果:

datediff(month, '2015-10-10', '2016-04-12')

所以你需要使用正确的Python函数,同时也要使用SQLAlchemy:

from sqlalchemy import func, text

func.datediff(text('month'), TableA.date, todays_date) >= 0

text('month')是将SQL中的字面量month传递给SQL服务器的一种方法:

In [16]: print(func.datediff(text('month'), datetime.now(), datetime.now()))
datediff(month, :datediff_1, :datediff_2)

literal_column 也可能起作用。

如果您想要更接近的翻译,请在Python中使用SQL函数替换todays_date,就像您在原始代码中使用的那样:

func.datediff(text('month'), TableA.date, func.getDate()) >= 0

调用本地函数'datediff'的参数计数不正确。 - Tarun
2
@tarun 数据库错误。这是用于 Microsoft SQL Server 的数据库,而你正在使用 MariaDB/MySQL。 - Ilja Everilä
对于MySQL/MariaDB,请删除第一个参数text('month')。MariaDB版本的datediff默认使用天数。 - The Bndr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接