如何使用pymysql通过存储过程将pyodbc mssql查询返回的列表插入到mysql中

问题描述 投票:0回答:1

我使用pyodbc从MSSQL数据库中提取数据,pyodbc返回列表中的数据集。然后需要将此数据传输到MySQL数据库。我在MySQL中编写了以下存储过程。

CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_int_pmt`(
    IN pmtamt DECIMAL(16,10),
        IN pmtdt DATETIME,
        IN propmtref VARCHAR(128),
        IN rtdinv_id INT(11)
    )
BEGIN
    INSERT INTO ay_financials.payment
    (
    pmtamt,
        pmtdt,
        propmtref,
        rtdinv_id
    )
VALUES
    (
    pmtamt,
        pmtdt,
        propmtref,
        rtdinv_id
    );

END

如果我当时插入一条记录,则该过程正常。所以,现在,我正在从我的MSSQL查询迭代列表并为每条记录调用该过程。我正在使用此代码:

cursor = cnxn.cursor()

cursor.execute("""  SELECT *
            FROM [%s].[dbo].[pmt]
            WHERE pmtdt BETWEEN '2018-01-01' AND '2018-12-31'""" %(database))

a = cursor.fetchmany(25)

cnxn.close()

import pymysql

# MySQL configurations
un = 'ssssssss'
pw = '****************'
db = 'ay_fnls'
h = '100.100.100.100'

conn = pymysql.connect(host=h, user=un, password=pw, db=db, cursorclass=pymysql.cursors.DictCursor)

cur = conn.cursor()

for ay in a:
    cur.callproc('sp_int_pmt',(ay.pmtamt,ay.pmtdt,ay.propmtref,ay.rtdinv_id))

conn.commit()

我将在生产中遇到的问题是这个列表每天将包含10,000-100,000。迭代该数据似乎不是处理此问题的优化方法。

如何使用MSSQL查询的完整列表,一次调用MySQL过程并插入所有相关数据?

python mysql python-3.x pyodbc pymysql
1个回答
0
投票

如何使用MSSQL查询的完整列表,一次调用MySQL过程并插入所有相关数据?

您不能使用您编写的存储过程来执行此操作。它一次只能插入一行,所以要插入n行,你必须调用n次。

此外,据我所知,您不能修改存储过程以插入n行而不使用临时表或其他一些解决方法,因为MySQL不支持存储过程的表值参数。

但是,如果使用常规INSERT语句和.executemany,则可以一次插入多行。 pymysql会将插入捆绑到一个或多个多行插入中

mssql_crsr = mssql_cnxn.cursor()
mssql_stmt = """\
SELECT 1 AS id, N'Alfa' AS txt
UNION ALL
SELECT 2 AS id, N'Bravo' AS txt
UNION ALL
SELECT 3 AS id, N'Charlie' AS txt
"""
mssql_crsr.execute(mssql_stmt)
mssql_rows = []
while True:
    row = mssql_crsr.fetchone()
    if row:
        mssql_rows.append(tuple(row))
    else:
        break

mysql_cnxn = pymysql.connect(host='localhost', port=3307,
                             user='root', password='_whatever_',
                             db='mydb', autocommit=True)
mysql_crsr = mysql_cnxn.cursor()
mysql_stmt = "INSERT INTO stuff (id, txt) VALUES (%s, %s)"
mysql_crsr.executemany(mysql_stmt, mssql_rows)

上面的代码在MySQL general_log中生成以下内容

190430 10:00:53     4 Connect   root@localhost on mydb
            4 Query INSERT INTO stuff (id, txt) VALUES (1, 'Alfa'),(2, 'Bravo'),(3, 'Charlie')
            4 Quit  

请注意,pymysql不能以相同的方式将调用捆绑到存储过程,因此如果您要使用

mysql_stmt = "CALL stuff_one(%s, %s)"

而不是常规INSERT,然后general_log将包含

190430  9:47:10     3 Connect   root@localhost on mydb
            3 Query CALL stuff_one(1, 'Alfa')
            3 Query CALL stuff_one(2, 'Bravo')
            3 Query CALL stuff_one(3, 'Charlie')
            3 Quit  
© www.soinside.com 2019 - 2024. All rights reserved.