我使用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过程并插入所有相关数据?
如何使用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