Python中如何用SQLAlchemy过滤SQL表中的datetime类型日期列
问题根因
你两种写法执行失败的核心原因是SQL中的日期字面量必须用单引号包裹,不加引号时SQL会把2021-11-08解析为数值减法运算(计算2021减11减8的结果),无法和datetime类型的price_date字段正常匹配。
可行解决方法
方法1:直接修改原生SQL的日期语法
给两个日期边界值添加单引号即可正常执行,注意如果需要包含11月12日全天的数据,建议把结束时间调整为当天的最晚时间,避免默认取0点导致12日的数据被过滤:
goog = pd.read_sql(""" SELECT dp.price_date, dp.adj_close_price FROM symbol AS sym INNER JOIN daily_price AS dp ON dp.symbol_id = sym.id WHERE sym.ticker = 'GOOG' AND dp.price_date BETWEEN '2021-11-08 00:00:00' AND '2021-11-12 23:59:59' ORDER BY dp.price_date ASC""", con = engine, index_col='price_date')
如果你的数据库支持日期截断函数,也可以写成下面的格式,写法更简洁,但注意字段上套函数可能会导致索引失效:
AND DATE(dp.price_date) BETWEEN '2021-11-08' AND '2021-11-12'
方法2:使用参数化查询(更推荐)
直接拼接SQL存在SQL注入风险,且需要手动处理日期格式,更稳妥的方式是通过pd.read_sql的params参数传递日期值,框架会自动处理类型转换和格式问题:
start_dt = "2021-11-08" end_dt = "2021-11-12" goog = pd.read_sql(""" SELECT dp.price_date, dp.adj_close_price FROM symbol AS sym INNER JOIN daily_price AS dp ON dp.symbol_id = sym.id WHERE sym.ticker = 'GOOG' AND dp.price_date BETWEEN %s AND %s ORDER BY dp.price_date ASC""", con = engine, params=(start_dt, end_dt), index_col='price_date')
注:不同数据库的参数占位符可能存在差异,如SQLite使用?作为占位符,可根据你使用的数据库类型调整即可。
内容的提问来源于stack exchange,提问作者yts61
相关产品推荐
相关产品推荐

