如何在 Pandas 中使用 sqlalchemy 执行具有多个日期参数的 sql 存储过程

Posted

技术标签:

【中文标题】如何在 Pandas 中使用 sqlalchemy 执行具有多个日期参数的 sql 存储过程【英文标题】:How to execute sql stored procedure with multiple date parameters using sqlalchemy in pandas 【发布时间】:2019-10-23 23:36:42 【问题描述】:

我可以在没有参数的情况下执行存储过程:

import pandas as pd
import sqlalchemy
import pyodbc
import datetime as dt  

engine = sqlalchemy.create_engine('mssql+pymssql://MyServer/MyDB')
df = pd.read_sql_query('EXEC dbo.TestProcedure' , engine)  # stored procedure without parameters
print(df)

但无法执行带参数的存储过程:

import pandas as pd
import sqlalchemy
import pyodbc
import datetime as dt  

myparams = ['2017-02-01','2017-02-28', None]  # None substitutes NULL in sql

engine = sqlalchemy.create_engine('mssql+pymssql://MyServer/MyDB')
df = pd.read_sql_query('EXEC PythonTest_Align_RSrptAccountCurrentMunich @EffectiveDateFrom=?,@EffectiveDateTo=?,@ProducerLocationID=?', engine, params=myparams)
print(df)

错误信息:

  File "src\pymssql.pyx", line 465, in pymssql.Cursor.execute
sqlalchemy.exc.ProgrammingError: (pymssql.ProgrammingError) (102, b"Incorrect syntax near '?'.DB-Lib error message 20018, severity 15:\nGeneral SQL Server error: Check messages from the SQL Server\n")
[SQL: EXEC PythonTest_Align_RSrptAccountCurrentMunich @EffectiveDateFrom=?,@EffectiveDateTo=?,@ProducerLocationID=?]
[parameters: ('2017-02-01', '2017-02-28', None)]
(Background on this error at: http://sqlalche.me/e/f405)

如何使用sqlalchemy 传递参数?

【问题讨论】:

【参考方案1】:

如果您使用参数占位符执行原始 SQL 查询,则必须使用 DBAPI 层支持的paramstyle。 pymssql 使用“格式”参数样式%s,而不是“qmark”参数样式?(pyodbc 使用)。

但是,您可以通过将查询包装在 SQLAlchemy text 对象中并始终使用“命名”参数样式来避免歧义。 SQLAlchemy 将自动将参数占位符转换为您正在使用的 DBAPI 的适当样式。例如调用一个名为echo_datetimes的存储过程:

import datetime
import sqlalchemy as sa

# ...

query = sa.text("EXEC echo_datetimes @p1 = :param1, @p2 = :param2")
values = 'param1': datetime.datetime(2020, 1, 1, 1, 1, 1),
          'param2': datetime.datetime(2020, 2, 2, 2, 2, 2)
df = pd.read_sql_query(query, engine, params=values)
print(df)
#              dt_start              dt_end
# 0 2020-01-01 01:01:01 2020-02-02 02:02:02

【讨论】:

【参考方案2】:

Read_sql 仅用于读取表格。要使用参数执行某些操作,请尝试使用

engine.execute(你的sql查询)#你可以尝试输入参数作为你给出的方式 在你的 sql engine.execution_options(autocommit=True)

【讨论】:

以上是关于如何在 Pandas 中使用 sqlalchemy 执行具有多个日期参数的 sql 存储过程的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 pandas sqlalchemy 和 psycopg2 处理 NaT

使用 SQLAlchemy 和 Pandas 插入数据 - Python

无法在 ETL 过程中使用 Pandas 和 SQLAlchemy 将列名从 CSV 更改为 SQL Server DB

使用 sqlalchemy 从 PostgreSQL 查询返回 Pandas 数据框

想要使用 pandas 和 sqlalchemy 从查询是变量(不和谐用户名)的数据库中选择所有内容

如何在 python 中使用 sqlalchemy 在查询中创建 sql server 表变量