如何在 pandas 中使用 sqlalchemy 执行具有多个日期参数的 sql 存储过程
How to execute sql stored procedure with multiple date parameters using sqlalchemy in pandas
我可以不带参数执行存储过程:
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
传递参数?
Read_sql 仅用于阅读表格。要使用参数执行某些操作,请尝试使用
engine.execute(your sql query)#you can try enter with parameters as you how to
在你的 sql
engine.execution_options(自动提交=真)
如果您正在执行带有参数占位符的原始 SQL 查询,那么您必须使用 DBAPI 层支持的 paramstyle。 pymssql 使用 "format" 参数样式 %s
,而不是 "qmark" 参数样式 ?
(pyodbc 使用)。
但是,您可以通过将查询包装在 SQLAlchemy text
对象中并始终使用 "named" 参数样式来避免歧义。 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
我可以不带参数执行存储过程:
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
传递参数?
Read_sql 仅用于阅读表格。要使用参数执行某些操作,请尝试使用
engine.execute(your sql query)#you can try enter with parameters as you how to 在你的 sql engine.execution_options(自动提交=真)
如果您正在执行带有参数占位符的原始 SQL 查询,那么您必须使用 DBAPI 层支持的 paramstyle。 pymssql 使用 "format" 参数样式 %s
,而不是 "qmark" 参数样式 ?
(pyodbc 使用)。
但是,您可以通过将查询包装在 SQLAlchemy text
对象中并始终使用 "named" 参数样式来避免歧义。 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