Вставка CLOB с помощью cx_Oracle

Я пытаюсь вставить CLOB, используя следующий код.

cursor = connection.cursor()
cursor.setinputsizes(HERP = cx_Oracle.CLOB)

cursor.execute("INSERT INTO myTable (FOO, BAR) VALUES (:FOO, :BAR)", FOO=val1, BAR=val2)
cursor.execute("INSERT INTO myTable2 (HERP) VALUES (:HERP)", HERP=val3) 
#len(HERP) 39097

Когда я запускаю сценарий БЕЗ cursor.setinputsizes(HERP = cx_Oracle.CLOB), он терпит неудачу во втором запросе С ValueError: string data too large, когда я запускаю сценарий с cursor.setinputsizes(HERP = cx_Oracle.CLOB), он терпит неудачу в первом запросе с DatabaseError: ORA-01036: illegal variable name/number. CLOB, который я пытаюсь вставить, содержит фрагмент кода (т. е. в нем много точек с запятой, запятых и скобок), "string".decode("ascii") возвращает u'string', так что проблема не в юникоде... верно? Я не знаю, являются ли какие-либо из этих вещей проблемами. Поле в базе данных в настоящее время является CLOB, однако я попробовал его с NCLOB, и поведение не изменилось.

Я также попробовал поле как BLOB, а затем использовал .encode("hex") для значения, которое я вставлял, снова такое же поведение.

Я также пробовал HERP = cursor.var(cx_Oracle.CLOB) вместо cursor.setinputsizes(HERP = cx_Oracle.CLOB), те же проблемы.

Я просматривал обсуждения на пользователях cx-oracle. список, но пока не повезло.

Это работает, если я использую эту строку cursor.execute("INSERT INTO myTable2 (HERP) VALUES (:HERP)", HERP="".join(set(val3)).encode("hex")), поэтому я не думаю, что это проблема с содержимым данных (это с BLOB).

Как я могу использовать cx_Oracle для вставки CLOB в базу данных Oracle?


person John    schedule 24.11.2012    source источник


Ответы (1)


Есть несколько возможных решений:

  1. Обновите cx_Oracle. Я не уверен, какую версию вы используете, но я использую python 2.7.2 с cx_Oracle 5.1, и я не получаю никаких ошибок при вставке 150 000 символов в столбец CLOB без использования setinputsizes вообще.
  2. Поскольку setinputsizes применяется к каждому последующему использованию курсора, просто измените его между этими различными инструкциями cursor.execute.

eg:

cursor = connection.cursor()
cursor.setinputsizes(FOO=None, BAR=None)
cursor.execute("INSERT INTO myTable (FOO, BAR) VALUES (:FOO, :BAR)", 
FOO=val1,  BAR=val2)
cursor.setinputsizes(HERP = cx_Oracle.CLOB)
cursor.execute("INSERT INTO myTable2 (HERP) VALUES (:HERP)", HERP=val3)
person Gerrat    schedule 04.12.2012