1

我有一个函数可以将一大块数据插入到 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。

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

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

4

1 回答 1

3

我有同样的问题。在我的情况下,它是由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 代码想要遍历指针列表,所以这就是你需要做的。

于 2011-06-17T07:45:23.360 回答