将存储过程选择结果读入pandas数据帧

joe*_*415 8 sql-server stored-procedures sqlalchemy pyodbc pandas

鉴于:

CREATE PROCEDURE my_procedure
    @Param INT
AS
    SELECT Col1, Col2
    FROM Table
    WHERE Col2 = @Param
Run Code Online (Sandbox Code Playgroud)

我希望能够将其用作:

import pandas as pd
import pyodbc

query = 'EXEC my_procedure @Param = {0}'.format(my_param)
conn = pyodbc.connect(my_connection_string)

df = pd.read_sql(query, conn)
Run Code Online (Sandbox Code Playgroud)

但这会引发错误:

ValueError: Reading a table with read_sql is not supported for a DBAPI2 connection. Use an SQLAlchemy engine or specify an sql query
Run Code Online (Sandbox Code Playgroud)

SQLAlchemy也不起作用:

import sqlalchemy
engine = sqlalchemy.create_engine(my_connection_string)
df = pd.read_sql(query, engine)
Run Code Online (Sandbox Code Playgroud)

抛出:

ValueError: Could not init table 'my_procedure'
Run Code Online (Sandbox Code Playgroud)

事实上,我可以pyodbc直接执行语句:

cursor = conn.cursor()
cursor.execute(query)
results = cursor.fetchall()
df = pd.DataFrame.from_records(results)
Run Code Online (Sandbox Code Playgroud)

有没有办法将这些过程结果直接发送到DataFrame?

as *_* if 9

SET NOCOUNT ON添加感谢@CRAFTY DBA后,这对我有用

sql_query = """SET NOCOUNT ON; EXEC db_name.dbo.StoreProc '{0}';""".format(input)

df = pandas.read_sql_query(sql_query , conn)
Run Code Online (Sandbox Code Playgroud)

  • 我也必须这样做。为了使我的查询正常工作,我必须在存储过程的变量周围使用单引号创建带有三引号的字符串。看起来像这样 `"""EXEC sProcedure 'variable1', 'variable2'"""` (2认同)

ste*_*r25 6

请改用read_sql_query()

看起来@joris (+1) 已经在问题正下方的评论中包含了这个,但我没有看到它,因为它不在答案部分。

使用 SQLA 引擎——除了 SQLAlchemy,Pandas 只支持 SQLite。然后使用read_sql_query()而不是 read_sql()。后者尝试自动检测您传递的是表名还是完整的查询,但它似乎与 'EXEC' 关键字效果不佳。使用 read_sql_query() 跳过自动检测并允许您明确指示您正在使用查询(还有一个 read_sql_table())。

import pandas as pd
import sqlalchemy

query = 'EXEC my_procedure @Param = {0}'.format(my_param)
engine = sqlalchemy.create_engine(my_connection_string)
df = pd.read_sql_query(query, engine)
Run Code Online (Sandbox Code Playgroud)


CRA*_*DBA 5

https://code.google.com/p/pyodbc/wiki/StoredProcedures

我不是python专家,但是SQL Server有时会返回语句执行的计数。例如,更新将告诉您更新了多少行。

只需使用“ SET NO COUNT;”即可。在批处理电话的最前面。这将删除插入,更新和删除的计数。

确保您使用的是正确的本机客户端模块。

看一下这个堆栈溢出示例。

它同时具有特别的SQL和调用存储过程的示例。

调用存储过程python

祝好运