在 cx_Oracle 上执行许多 CLOB 元素

Posted

技术标签:

【中文标题】在 cx_Oracle 上执行许多 CLOB 元素【英文标题】:executemany of CLOB elements on cx_Oracle 【发布时间】:2011-09-02 03:27:48 【问题描述】:

我有一个函数可以将一大块数据插入到 oracle 数据库中。我正在尝试通过使用 executemany 来实现这一目标。

我的函数如下所示:

  def InsertChunk(self):
    try:
      if len(self.list_dict_values) >= self.chunksize:
        self.db.cursor.executemany(
          str(self.insert_sql),
          self.list_dict_values
         )
        self.list_dict_values = []
    except cx_Oracle.Error, e:
      print e

该函数被许多表使用,如果这些表中没有 CLOB 列,则可以正常工作。仅当 chunksize 设置为 1 或 2 时,它才适用于具有 CLOB 列的表。有时它适用于 3,但大多数时候它不起作用。当块大小为 4 时,我什至让它工作了一次。我正在使用这个函数将块大小设置为 1000 左右以加快进程。

当chunksize设置为3时,有时会返回如下错误:

ORA-24813:无法发送或接收不受支持的 LOB。

有时它会说已中止并停止脚本。

知道为什么这个脚本每次使用相同的参数运行时都会有不同的行为吗?

【问题讨论】:

除了if 语句之外,chunksize 在哪里使用? 【参考方案1】:

我遇到了同样的问题。就我而言,这是由于错误地使用了cx_Oracle 变量类型造成的。当填写我的list_dict_values 时,我正在做这样的事情:

for row in list_dict_values:
  for key, val in row.iteritems():
     v = cursor.var(cx_Oracle.CLOB)
     v.setvalue(0, val)
     row[key] = v
..
InsertChunk()

您需要创建一个具有数组大小的单个变量,而不是许多小变量,然后在字典的每一行中引用它。

lobdict = 
for k in list_dict_vals[0].keys():
   lobdict[k] = cursor.var(cx_Oracle.CLOB, arraysize=len(list_dict_vals))
for rownum, row in enumerate(list_dict_values):
  for key, val in row.iteritems():
     lob = lobdict[key]
     lob.setvalue(rownum, val)
     row[key] = lob
...
InsertChunk()

将每一行设置为相同的值似乎很奇怪,但它可以工作 - 在内部,oracle 代码想要遍历指针列表,所以这就是你需要做的。

【讨论】:

以上是关于在 cx_Oracle 上执行许多 CLOB 元素的主要内容,如果未能解决你的问题,请参考以下文章

python3 UnicodeEncodeError错误,cx_oracle模块执行sql报错:UnicodeEncodeError: 'ascii' codec can't

更新表时 cx_Oracle 执行/executemany 错误

是否可以在变量 CLOB 中的执行代码中指定另一个 CLOB (JSON) 中的值

如何更新没有根元素的clob oracle中的xml元素

从clob列中提取xml元素时出错

使用 cx_Oracle 中 csv 文件中的变量更新数据库