【问题标题】:executemany: Failed executing the operation; Could not process parameters (Python)executemany:执行操作失败;无法处理参数(Python)
【发布时间】:2019-10-03 13:39:48
【问题描述】:

我已经编写了一些 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 查询)和两个连接,这些都可以正常工作。任何人都可以看到这些问题吗?

【问题讨论】:

  • MySQL 在 SQL Server 等标识符周围使用反引号,而不是括号 [...]
  • 我已经用从插入查询中取出的括号更新了上面的代码(另一个是使用 SQL 服务器运行的)。我仍然遇到同样的错误。
  • 可能是数据问题。在插入之前尝试打印 SageResult 以查看内容。
  • 我添加了一个打印并更改了它,因此它只在选择中拉出一个结果,以便更容易查看。你能发现任何问题吗? (见上面的更新输出)
  • 我怀疑SageResultpyodbc.Row 对象的元组,mysql.connector 可能不喜欢那些。请参阅 this answer 了解创建元组列表的方法。

标签: python mysql sql pyodbc


【解决方案1】:

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

【讨论】:

  • 谢谢。这清除了大部分错误。现在它只是说“错误:执行操作失败;无法处理参数”。那是 Insert_VPS 函数中的例外。
  • 我猜你不应该在 SQL 查询中使用 []
  • [] 取自 SQL 服务器中生成的查询,该查询运行良好,因此我看不出这是问题所在。
  • 你确定SageResult 是一个元组吗?在执行executemany()之前,您应该检查类型及其元素。
  • 我不确定。我对 python 很陌生,所以我真的不知道 SageResult 被输出为什么(我假设是一个标准数组)。
【解决方案2】:

考虑解决方法,因为特殊的 datetime 和 decimal 类型可能无法有效地从 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 查询。此查询将使用 Access 的 SQL 方言,它支持 TOP 子句和括号名称。结果应立即在 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>')
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-04
    • 1970-01-01
    • 1970-01-01
    • 2019-11-05
    • 1970-01-01
    • 2018-06-19
    • 2019-06-25
    相关资源
    最近更新 更多