【问题标题】:pyodbc: ('Params must be in a list, tuple, or Row', 'HY000') with NumPy datapyodbc: ('Params must be in a list, tuple, or Row', 'HY000') with NumPy data
【发布时间】:2017-02-16 23:28:50
【问题描述】:

我正在尝试使用 Python 3 通过 pyodbc 将元组列表插入 MS SQL 表中。这可行:

conn_string = (('DRIVER=FreeTDS;'
                'SERVER={};'
                'PORT=1433;'
                'DATABASE={};'
                'UID={};'
                'PWD={};'
                'TDS_Version=8.0;')
               .format(server, db, user, pwd))
sql = """
insert into Table1(field1, field2, field3) values (?, ?, ?)
"""

cursor.executemany(sql, [('1175B57E-7A10-4BAC-B22E-457C8266C0F2', '1D111FA5-A65D-4F77-A3AB-78B80BAF0C0B', 2),
 ('C60FA1C9-7656-4EBF-A577-44CBF0C641F4', '365FB706-9F7F-4ED4-AB88-927AE1F762A6', 1),
 ('2DF071CE-ABDF-4119-9573-2B0CA2B99C9C', '590E266D-810C-4DC2-BA5A-BAC05A9982C4', 0),
 ('EB794EF9-5FF4-49D3-B81E-F14F69C09306', '1D6E0C95-DF96-45D5-B8F3-211D825A160F', 0),
 ('EB794EF9-5FF4-49D3-B81E-F14F69C09306', '17D2EC66-845F-495D-9020-91E144B2E595', 0),
 ('EB794EF9-5FF4-49D3-B81E-F14F69C09306', '3A694B33-39F4-4F5B-899B-9B27810E4D82', 1),
 ('2DF071CE-ABDF-4119-9573-2B0CA2B99C9C', '4EE1D6F4-4A1E-4316-93D5-2AE1F461A193', 0),
 ('410DE087-1ADF-4EEA-BCE6-D7A1124E2A51', '17D2EC66-845F-495D-9020-91E144B2E595', 0),
 ('C60FA1C9-7656-4EBF-A577-44CBF0C641F4', '250256D4-4A3A-48E0-BCBA-7CD89011D81F', 1),
 ('2DF071CE-ABDF-4119-9573-2B0CA2B99C9C', '4D363718-FE0C-4257-8E4C-5C9A024BAEFF', 0)])

但事实并非如此:

params = list(row for row in data_table.round(0).head(10).to_records(index=False))

cursor.executemany(sql, params)

产生这个错误:

('Params must be in a list, tuple, or Row', 'HY000')

即使params 的输出是:

[('1175B57E-7A10-4BAC-B22E-457C8266C0F2', '1D111FA5-A65D-4F77-A3AB-78B80BAF0C0B', 2),
     ('C60FA1C9-7656-4EBF-A577-44CBF0C641F4', '365FB706-9F7F-4ED4-AB88-927AE1F762A6', 1),
     ('2DF071CE-ABDF-4119-9573-2B0CA2B99C9C', '590E266D-810C-4DC2-BA5A-BAC05A9982C4', 0),
     ('EB794EF9-5FF4-49D3-B81E-F14F69C09306', '1D6E0C95-DF96-45D5-B8F3-211D825A160F', 0),
     ('EB794EF9-5FF4-49D3-B81E-F14F69C09306', '17D2EC66-845F-495D-9020-91E144B2E595', 0),
     ('EB794EF9-5FF4-49D3-B81E-F14F69C09306', '3A694B33-39F4-4F5B-899B-9B27810E4D82', 1),
     ('2DF071CE-ABDF-4119-9573-2B0CA2B99C9C', '4EE1D6F4-4A1E-4316-93D5-2AE1F461A193', 0),
     ('410DE087-1ADF-4EEA-BCE6-D7A1124E2A51', '17D2EC66-845F-495D-9020-91E144B2E595', 0),
     ('C60FA1C9-7656-4EBF-A577-44CBF0C641F4', '250256D4-4A3A-48E0-BCBA-7CD89011D81F', 1),
     ('2DF071CE-ABDF-4119-9573-2B0CA2B99C9C', '4D363718-FE0C-4257-8E4C-5C9A024BAEFF', 0)]

【问题讨论】:

  • 刚刚测试,我无法重现您的问题。你的 RDMS 是什么?
  • 谢谢。它是 MS SQL Server 2014。如果有帮助,字符串字段是 COLLATE "SQL_Latin1_General_CP1_CI_AS"。
  • params 中的内容是列表,列表不能作为函数参数传递。尝试将其更改为 params = (('A', 'B', 2),('C', 'D', 1),('E', 'F', 0)) 并告诉我
  • 我想我明白了——to_records() 实际上创建了一个 numpy.records 列表。我把它改成了params = list(tuple(row) for row in data_table.head(10).values),它可以工作了。

标签: python pandas numpy pyodbc


【解决方案1】:

正如问题的 cmets 所述,问题在于

cursor.executemany(sql, params)

失败是因为

params = list(row for row in data_table.round(0).head(10).to_records(index=False))

没有返回“list[s]、tuple[s] 或 [pyodbc] Row[s]”列表,而是返回“numpy.records”列表。解决方案是转换“记录”,使params 包含一个元组列表:

params = list(tuple(row) for row in data_table.head(10).values)

【讨论】:

    【解决方案2】:

    我认为重要的是要指出,如果您使用tuple(__item__),您的字符串将被每个字符分隔...将您的字符串视为 C++ const char 指针。元组正在获取 const chars 指针项并将所有元素放入一个元组中。要阻止这种情况,您可以将您的字符串放在一个列表中:tuple([__string__])。该列表不会留在元组中,它只是说将整个 const char 指针项作为一个元素放入我的元组中。希望这对您有所帮助,最近在工作中遇到了这个问题。

    【讨论】:

    • 感谢您抽出宝贵时间提供答案。请考虑仔细阅读问题。您回答的不是 OP 正在寻找的。不要放置来自其他编程语言的引用。寻找此答案的人可能不知道该语言。
    猜你喜欢
    • 1970-01-01
    • 2017-12-03
    • 2023-04-10
    • 1970-01-01
    相关资源
    最近更新 更多