SQLAlchemy查询Access数据库日期条件语法错误求助
问题
我在Python中使用SQLAlchemy实现了如下查询:
url = URL.create( drivername="access+pyodbc", query={ "odbc_connect": connStr, }, ) with create_engine(url).connect() as con: sql_get_anag = text(f"SELECT Tipo_Presenza FROM Presenza WHERE ID_Anagrafica = {IDValue} AND Giorno > {current_day_insert} AND Giorno < {current_day_insert_1}") Presenza_tab = pd.read_sql_query(sql_get_anag, con)
执行后返回如下错误:
Exception has occurred: ProgrammingError (pyodbc.ProgrammingError) ('42000', "[42000] [Microsoft][Driver ODBC Microsoft Access] Errore di sintassi (operatore mancante) nell'espressione della query 'ID_Anagrafica = 4 AND Giorno > 24-05-24 00:00:00 AND Giorno < 25-05-24 00:00:00'. (-3100) (SQLExecDirectW)") [SQL: SELECT Tipo_Presenza FROM Presenza WHERE ID_Anagrafica = 4 AND Giorno > 24-05-24 00:00:00 AND Giorno < 25-05-24 00:00:00] (Background on this error at: https://sqlalche.me/e/20/f405) pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][Driver ODBC Microsoft Access] Errore di sintassi (operatore mancante) nell'espressione della query 'ID_Anagrafica = 4 AND Giorno > 24-05-24 00:00:00 AND Giorno < 25-05-24 00:00:00'. (-3100) (SQLExecDirectW)")
我认为是WHERE条件中的日期语法不正确,但不知道正确语法是什么。我尝试添加/移除日期参数的单引号但未成功,期望能正确执行该SELECT查询,恳请提供解决建议。
解决建议
核心问题
直接用f-string拼接SQL语句,不仅存在SQL注入风险,还不符合Access的日期语法要求——Access日期字面量需要用#包裹,而非单引号,且需保证日期格式为数据库可识别的标准格式。
最优方案:使用参数化查询
SQLAlchemy的text()支持参数绑定,能自动处理数据格式转换,同时规避注入风险,代码修改如下:
url = URL.create( drivername="access+pyodbc", query={"odbc_connect": connStr}, ) with create_engine(url).connect() as con: # 用占位符定义参数,避免直接拼接字符串 sql_get_anag = text(""" SELECT Tipo_Presenza FROM Presenza WHERE ID_Anagrafica = :id_value AND Giorno > :start_date AND Giorno < :end_date """) # 通过params传入参数,SQLAlchemy自动适配Access格式 Presenza_tab = pd.read_sql_query( sql_get_anag, con, params={ "id_value": IDValue, "start_date": current_day_insert, "end_date": current_day_insert_1 } )
关键细节说明
- 日期格式适配:确保
current_day_insert和current_day_insert_1是Python的datetime对象,而非字符串。如果是字符串格式,先转换为datetime:from datetime import datetime current_day_insert = datetime.strptime(current_day_insert_str, "%d-%m-%y %H:%M:%S") current_day_insert_1 = datetime.strptime(current_day_insert_1_str, "%d-%m-%y %H:%M:%S") - 为什么单引号没用:Access的日期语法要求用
#(如#2024-05-24 00:00:00#),但手动拼接#仍有注入风险,参数化查询是最安全可靠的方式。
内容的提问来源于stack exchange,提问作者marionardo
相关产品推荐
相关产品推荐

