我有一个将一大块数据插入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,但大多数情况下它不适用。当chunksize为4时,我甚至让它工作一次。我正在使用这个函数将块大小设置为1000左右,以加快这个过程。
当chunksize设置为3时,有时会返回以下错误:
ORA-24813:无法发送或接收不受支持的LOB。
有时它会中止并停止剧本。
任何想法为什么每次使用相同的参数运行此脚本时都会有不同的行为?
答案 0 :(得分: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()
您需要使用arraysize创建一个变量,然后在dict的每一行中引用它,而不是许多小变量。
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代码想要遍历一个指针列表,这就是你需要做的。