Выполнение множества элементов CLOB в cx_Oracle

1

У меня есть функция, которая вставляет фрагмент данных в базу данных оракула. Я пытаюсь достичь этого, используя 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 имеет различное поведение при каждом запуске с теми же параметрами?

  • 0
    Где используется chunksize , кроме оператора if ?
Теги:
cx-oracle
executemany

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()

Вместо многих небольших переменных вам нужно создать одну переменную с массивом, а затем указать ее в каждой строке вашего 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()

Кажется странным установить каждую строку в одно и то же значение, но она работает - внутри код оракула хочет перебирать список указателей, так что вам нужно сделать.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню