executemany:执行操作失败;无法处理参数(Python)

时间:2019-05-16 09:55:24

标签: python mysql sql pyodbc

我已经编写了一些python代码,这些代码实际上将从一个数据库(SQL Server 2008)中获取数据并将其插入到另一个数据库(MySQL)中。我是python的新手,所以很难在我的代码中找到错误。

我的代码是:

import mysql.connector
import pyodbc

def insert_VPS(SageResult):
    query = """
INSERT INTO SOPOrderReturn(SOPOrderReturnID,DocumentTypeID,DocumentNo,DocumentDate,CustomerID,CustomerTypeID,CurrencyID,SubtotalGoodsValue,TotalNetValue,TotalTaxValue,TotalGrossValue,SourceTypeID,SourceDocumentNo)
VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"""
    try:
        mydbVPS = mysql.connector.connect(
          host="serveraddress",
          user="username",
          passwd="password;",
          database="databse"
        )

        VPScursor = mydbVPS.cursor()
        print(SageResult)
        VPScursor.executemany(query, SageResult)


        mydbVPS.commit()
    except Exception as e:
        print('InsertError:', e)

    finally:
        VPScursor.close()
        mydbVPS.close()

def main():
    selectQuery = """
SELECT TOP 1 [SOPOrderReturnID]
      ,[DocumentTypeID]
      ,[DocumentNo]
      ,[DocumentDate]
      ,[CustomerID]
      ,[CustomerTypeID]
      ,[CurrencyID]
      ,[SubtotalGoodsValue]
      ,[TotalNetValue]
      ,[TotalTaxValue]
      ,[TotalGrossValue]
      ,[SourceTypeID]
      ,[SourceDocumentNo]
  FROM [Live].[dbo].[SOPOrderReturn]
"""


    try:
        mydbSage = pyodbc.connect('Driver={SQL Server};'
                      'Server=CRMTEST;'
                      'Database=Live;'
                      'UID=sa;'
                      'PWD=password;')

        Sagecursor = mydbSage.cursor()

        Sagecursor.execute(selectQuery)
        SageResult = tuple(Sagecursor.fetchall())


        mydbSage.commit()
    except Exception as e:
        print('MainError:', e)

    finally:
        Sagecursor.close()
        mydbSage.close()

    insert_VPS(SageResult)


if __name__ == '__main__':
    main()

我得到的错误:

D:\xampp\htdocs\stripe\group\beta>sql-sync.py
((10447177, 0, '0000091897', datetime.datetime(2010, 8, 18, 0, 0), 186150, 1, 1, Decimal('18896.95'), Decimal('18896.95'), Decimal('3779.39'), Decimal('22676.34
'), 0, ''),)
InsertError: Failed executing the operation; Could not process parameters

我已经测试了选择查询(但未测试INSERT),并且两个连接都在更基本的脚本中进行了测试,并且都可以正常工作。谁能看到问题?

2 个答案:

答案 0 :(得分:0)

应该是except Exception as e而不是except Error as e:

答案 1 :(得分:0)

考虑解决方法,因为特殊的日期时间和十进制类型可能无法有效地从pyodbc转换为mysql连接器DB-API。

CSV

使用MySQL的快速LOAD DATA方法使用流行的数据传输形式。

import csv
...

# SQL SERVER CSV EXPORT
mydbSage = pyodbc.connect('...')

Sagecursor = mydbSage.cursor()
Sagecursor.execute(selectQuery)
SageResult = Sagecursor.fetchall()

with open("/path/to/SageResult.csv", "w", newline='') as csv_file:
    cw = csv.writer(csv_file)
    cw.writerow([i[0] for i in Sagecursor.description])    # WRITE HEADERS
    cw.writerows(SageResult)                               # WRITE DATA ROWS  


# MYSQL CSV IMPORT
mydbVPS = mysql.connector.connect(...)

query = """LOAD DATA LOCAL INFILE '/path/to/SageResult.csv'
           INTO TABLE SOPOrderReturn
           FIELDS TERMINATED BY
           ENCLOSED BY '"'
           LINES TERMINATED BY '\r\n'
        """
VPScursor = mydbVPS.cursor()
VPScursor.execute(query)

PyODBC

使用相同的API运行两个数据库连接,这需要为您的操作系统下载MySQL ODBC driver,并替换mysql.connector)。这样可以解决对这些特定类型的处理。

# SQL SERVER SELECT QUERY
mydbSage = pyodbc.connect(driver="SQL Server", host="CRMTEST", database="LIVE",
                          uid="sa", pwd="password")

Sagecursor = mydbSage.cursor()
Sagecursor.execute(selectQuery)
SageResult = tuple(Sagecursor.fetchall())

# MYSQL APPEND QUERY
mydbVPS = pyodbc.connect(driver="ODBC Driver Name", host="hostname",
                         uid="username", pwd="password", database="database")

query = """INSERT INTO SOPOrderReturn (SOPOrderReturnID, DocumentTypeID, DocumentNo,
                                       DocumentDate, CustomerID, CustomerTypeID,
                                       CurrencyID, SubtotalGoodsValue, TotalNetValue,
                                       TotalTaxValue, TotalGrossValue, SourceTypeID,
                                       SourceDocumentNo) 
           VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, , ?, ?, ?)
        """

VPScursor = mydbVPS.cursor()
VPScursor.execute(query, SageResult)

MS Access

将Office应用程序用作两个关系数据库之间的媒介。由于您使用的是SQL Server,因此您可以使用Microsoft Office,并可以使用其DBMS Office应用程序:MS Access。

从技术上讲,MS Access类似于phpMyAdmin,它是数据库的GUI控制台(其中的应用程序通常为conflated with its engine),但Access不仅限于任何一个数据库,而且可以补充其默认数据库Jet / ACE SQL引擎,以及任何已知的后端数据和数据库源。

  1. 创建两个linked tables(使用ODBC连接)到单独的RDBMS。
  2. 在链接表上创建然后运行INSERT...SELECT查询。该查询将使用支持TOP子句和方括号名称的Access的SQL方言。结果应立即在MySQL表中传播。

    INSERT INTO SOPOrderReturn_mysql_linked 
    SELECT TOP 50 [SOPOrderReturnID]
           ,[DocumentTypeID]
           ,[DocumentNo]
           ,[DocumentDate]
           ,[CustomerID]
           ,[CustomerTypeID]
           ,[CurrencyID]
           ,[SubtotalGoodsValue]
           ,[TotalNetValue]
           ,[TotalTaxValue]
           ,[TotalGrossValue]
           ,[SourceTypeID]
           ,[SourceDocumentNo]
    FROM SOPOrderReturn_mssql_linked
    
  3. 实际上,在链接已保存数据库中的表之后,让Python在查询中运行。 MS Access ODBC驱动程序可能已经与Office应用一起安装,或者可以与downloaded redistributable一起安装。

    # LIST OF INSTALLED DRIVERS
    print(pydbc.drivers())
    
    # MS ACCESS APPEND QUERY
    constr = r"DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ={'C:\\Path\\To\\Database\\File.accdb'};"
    
    accdb = pyodbc.connect(constr)
    cur = accdb.cursor()
    cur.execute('<APPEND QUERY USING LINKED TABLES>')