Выполнение множества элементов CLOB в cx_Oracle - PullRequest
1 голос
/ 26 мая 2011

У меня есть функция, которая вставляет порцию данных в базу данных 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. Он работает с таблицами со столбцами CLOB, только если для chunksize задано значение 1 или 2. Иногда он работает с 3, но в большинстве случаев это не так. Я даже работал один раз, когда размер фрагмента был 4. Я использую эту функцию, чтобы установить размер фрагмента около 1000, чтобы ускорить процесс.

Когда размер фрагмента равен 3, иногда возвращается следующая ошибка:

ORA-24813: невозможно отправить или получить неподдерживаемый большой объект.

А иногда он говорит, что прерван и останавливает сценарий.

Есть идеи, почему этот скрипт имеет разное поведение при каждом запуске с одинаковыми параметрами?

1 Ответ

3 голосов
/ 17 июня 2011

У меня была такая же проблема.В моем случае это было вызвано неправильным использованием типов переменных 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()

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...