У меня есть функция, которая вставляет фрагмент данных в базу данных оракула. Я пытаюсь достичь этого, используя 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. Он работает с таблицами с столбцами CLOB только тогда, когда chunksize установлен в 1 или 2. Иногда он работает на 3, но большую часть времени он этого не делает. Я даже получил его работу один раз, когда chunksize было 4. Я использую эту функцию, чтобы установить размер блока примерно на 1000, чтобы ускорить процесс.
Если для параметра chunksize установлено значение 3, иногда он возвращает следующую ошибку:
ORA- 24813: не удается отправить или получить неподдерживаемый LOB.
И иногда он говорит о прерывании и останавливает script.
Любая идея, почему этот script имеет различное поведение при каждом запуске с теми же параметрами?
У меня была та же проблема. В моем случае это было вызвано неправильным использованием типов переменных 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()
Вместо многих небольших переменных вам нужно создать одну переменную с массивом, а затем указать ее в каждой строке вашего 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()
Кажется странным установить каждую строку в одно и то же значение, но она работает - внутри код оракула хочет перебирать список указателей, так что вам нужно сделать.
chunksize
, кроме оператораif
?