使用SQLAlchemy 2.0删除90天前数据遇参数错误如何解决?
问题
我正在学习SQLAlchemy,想要删除当前日期起算超过X天的旧数据。尝试执行以下代码:
from datetime import datetime, timedelta import sqlalchemy db_con_string = 'Driver={ODBC Driver 17 for SQL Server};Server=tcp...' connection_url = sqlalchemy.engine.URL.create("mssql+pyodbc", query={"odbc_connect": db_con_string}) engine = sqlalchemy.create_engine(connection_url) with engine.begin() as sql_conn: command = 'delete myschema.Logs where [DateTimeSent] < ?' params = ((datetime.utcnow() + timedelta(days=-90)), ) sql_conn.execute(sqlalchemy.sql.text(command), params)
执行后报错:sqlalchemy.exc.ArgumentError: List argument must consist only of tuples or dictionaries
使用的是SQLAlchemy 2.0.23版本,该如何修复这个错误?
解决方案
这个错误的核心是参数传递格式不符合SQLAlchemy 2.0的要求,和datetime对象本身无关,以下是几种修复方式:
简化参数为单层单元素元组:你当前的
params是嵌套元组((datetime_obj,),),SQLAlchemy 2.0不接受这种嵌套结构,改成单层即可:params = (datetime.utcnow() + timedelta(days=-90), ) sql_conn.execute(sqlalchemy.sql.text(command), params)用列表包裹参数:直接把参数放到列表中,也是符合要求的格式:
params = [datetime.utcnow() + timedelta(days=-90)] sql_conn.execute(sqlalchemy.sql.text(command), params)使用命名参数(推荐,可读性更强):修改SQL语句为命名占位符,搭配字典传递参数,能避免位置参数的混淆:
command = 'delete myschema.Logs where [DateTimeSent] < :cutoff_date' params = {"cutoff_date": datetime.utcnow() + timedelta(days=-90)} sql_conn.execute(sqlalchemy.sql.text(command), params)
注:Python datetime对象可以被SQLAlchemy 2.0自动转换为SQL Server对应的日期类型,无需额外处理。
内容的提问来源于stack exchange,提问作者Vitamin C
相关产品推荐
相关产品推荐

