【问题标题】:cx_oracle executemany is not inserting all fieldscx_oracle executemany 未插入所有字段
【发布时间】:2018-08-05 06:16:36
【问题描述】:

我正在尝试使用 cx_oracle executemany 将行批量插入到 Oracle 数据库表中。

我的问题是 executemany 是在不抛出错误的情况下“跳过”某些字段,我正在努力理解为什么。

我要插入的值存储在一个列表中:

print (parsed_results[0]) 
['100700000005', '00000005006', '20180223', 'Transaction Deposit 1', '1', '', 'N'] 
print (parsed_results[1])
['100700000005', '00000005006', '20180223', 'Transaction Deposit 2', '1', '', 'N'] 
etc

如果我遍历列表并一次插入一个,一切正常。但是,当我使用 executemany 时,某些字段几乎是随机跳过的。

代码:

connectString = 'user/password@{dba}'.format(dba=dbname)
connection = cx_Oracle.connect(connectString)
cursor = connection.cursor()
cursor.arraysize = 5000
s_sql_insert = '''INSERT INTO My_Schema.My_table(
    ID, ACCT_ID, DATE, TYPE,COUNT, REF_NO, REV) 
    VALUES (:ID, :ACCT_ID, :DATE, :TRAN, :COUNT, :REF_NO, :REV)'''

try:
    cursor.prepare(s_sql_insert)
except Exception as e: 
    logging.error ('Failed to prepare cursor!')
    logging.error('Reason: %s', e)

try:
    cursor.executemany(None, (parsed_results))
except cx_Oracle.DatabaseError as e:
    logging.error ('Failed to insert rows!')
    logging.error('Reason: %s', e)
connection.commit()
cursor.close()
connection.close()

有谁知道为什么会发生这种情况,或者我如何获得有关任何错误的更多信息?

【问题讨论】:

  • 您确定parsed_results 中的每个 项都具有相同的7 长度吗?仔细检查随机跳过,因为参数是按位置传递的。以及日志文件中的任何内容?
  • 逐行遍历列表并执行 cursor.execute(s_sql_insert, (row)) 工作正常。我认为 parsed_results 中的数据集让 executemany 感到不安
  • 并且没有异常记录在日志文件中逐行executeexecutemany?我们在谈论多少行?您真的遍历了所有行还是只过滤了子集行?
  • 您使用的是什么版本的 cx_Oracle?你能提供一个完整的案例来证明这个问题吗?

标签: python cx-oracle


【解决方案1】:

问题是这样的,根据文档,您首先要做的是cursor.prepare(statement)

This can be used before a call to execute() to define the statement 
that will be executed. When this is done, the prepare phase will not be 
performed when the call to execute() is made with None or the same 
string object as the statement.

当您在代码中调用 execute 时,您会专门使用 None,这意味着您的准备好的语句将不会被使用。

只需在executemany 函数调用中执行您的语句。此外,要查看错误,您可以在 cursor.executemany 调用中使用 batcherrors=True 标志,以便您可以在其后使用 cursor.getbatcherrors() 来检索所有错误。这一切都直接来自文档。

【讨论】:

【解决方案2】:

可能是由于命名参数与编号参数。考虑将准备好的语句调整为带编号的占位符:

s_sql_insert = '''INSERT INTO My_Schema.My_table(
    ID, ACCT_ID, DATE, TYPE,COUNT, REF_NO, REV) 
    VALUES (:1, :2, :3, :4, :5, :6, :7)'''

或者,将 parsed_results 转换为字典列表以映射到命名占位符。您可以通过字典理解来做到这一点:

parse_results_dict = [{'ID': i[0],
                       'ACCT_ID' : i[1], 
                       'DATE': i[2], 
                       'TRAN': i[3],
                       'COUNT': i[4], 
                       'REF_NO': i[5], 
                       'REV': i[6]} for i in parse_results]


s_sql_insert = '''INSERT INTO My_Schema.My_table(
    ID, ACCT_ID, DATE, TYPE, COUNT, REF_NO, REV) 
    VALUES (:ID, :ACCT_ID, :DATE, :TRAN, :COUNT, :REF_NO, :REV)'''

cursor.prepare(s_sql_insert)
cursor.executemany(None, parsed_results_dict)
connection.commit()

【讨论】:

    猜你喜欢
    • 2021-07-17
    • 2019-05-02
    • 2011-10-01
    • 2014-05-03
    • 2012-12-26
    • 2013-12-22
    • 2019-10-17
    • 2019-07-10
    • 1970-01-01
    相关资源
    最近更新 更多