我可以将 pyodbc executemany 与 sql 存储过程一起使用吗?

Posted

技术标签:

【中文标题】我可以将 pyodbc executemany 与 sql 存储过程一起使用吗?【英文标题】:Can I use pyodbc executemany with sql stored procedure? 【发布时间】:2019-12-24 08:30:32 【问题描述】:

我需要将大量数据从 pandas 数据帧写入 MS-SQL 表(一次 1000 行甚至更多行)。

我正在使用pyodbc executmanyfast_executemany=True,否则每张桌子都需要几个小时。现在,出于安全原因,IT 人员希望我开始使用存储过程而不是直接访问数据库。

问题是,从我看到的情况来看,SQL是,怎么说呢,不如python灵活,而且我必须声明每个传递给SP的变量,所以我看不到如何传递使用df.values.tolist() 的SP,就像我今天使用executemany 函数直接访问数据库一样。

例如,假设我有一个数据框 df:

身份证姓名工资

1 乔希 10000

2 迈克尔 5000

3 萨拉 8000

今天我会使用:

cursor.fast_executemany = True
insert_str = "INSERT INTO [%s].[%s] VALUES (?, ?, ?)"
cursor.executemany(insert_str % (scheme, table), df.values.tolist()])

所有数据框都将立即(并且快速)插入到表中。但是,调用 SP 似乎不可能做到这一点。

有没有办法将pyodbc executemany 与存储过程一起使用?

【问题讨论】:

“我必须声明传递给 SP 的每个变量”不一定。如果您的 SP 只有输入参数,并且 DataFrame 中的列与这些输入参数以完全相同的顺序 对应,那么 ODBC CALL yourSp(?,?,...) 语法应该可以正常工作。请edit您的问题,并提供一个简单示例,说明您要完成的工作以及收到的任何错误(或意外结果)。 Tnx。我已经编辑了一个需要的例子。没有尝试使用 CALL mySp(?, ?, ?),因为我看不到 df.values.tolist() 适合的位置。 我会尝试的第一件事是cursor.executemany("CALL mySp(?, ?, ?)", df.values.tolist()) 【参考方案1】:

是的,我们可以在 SQL Server 中将executemany 与存储过程一起使用:

表:

CREATE TABLE [dbo].[Table_1](
    [id] [int] NOT NULL,
    [name] [nvarchar](50) NULL,
    [salary] [int] NULL,
 CONSTRAINT [PK_Table_1] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

存储过程:

CREATE PROCEDURE [dbo].[Table_1_insert] 
    @id int = 0, 
    @name nvarchar(50),
    @salary int
AS
BEGIN
    SET NOCOUNT ON;
    INSERT INTO Table_1 (id, name, salary) VALUES (@id, @name, @salary);
END

Python 代码:

df = pd.DataFrame(
    [(1, 'Josh', 10000), (2, 'Michael', 5000), (3, 'Sara', 8000)], 
    columns=['id', 'name', 'salary'])
crsr.executemany("CALL dbo.Table_1_insert(?, ?, ?)", df.values.tolist())
cnxn.commit()

【讨论】:

以上是关于我可以将 pyodbc executemany 与 sql 存储过程一起使用吗?的主要内容,如果未能解决你的问题,请参考以下文章

使用 cursor.executemany(query, df.itertuples(index=False)) 的 pyodbc 批量数据导入挑战

Linux上的pyodbc fast_executemany在插入时出现乱码

Python sqlite:使用未指定数量的参数的executemany()

如何在 CrateDB 中使用 python 执行批量插入?

如何通过 executemany() 语句转换 pandas 数据框以进行插入?

将数据作为列表加载到 Netezza 非常慢