cx_Oracle.NotSupportedError: значение Python не может быть преобразовано в значение базы данных - PullRequest
0 голосов
/ 06 июня 2018

Я пытаюсь прочитать данные из одной таблицы и записать в другую таблицу в другой базе данных, используя Python и cx_Oracle.

Мой скрипт работает нормально, когда я читаю записи по одной, но когда я выбираю более 100 записей, используя fetchmany, скрипт завершается ошибкой

cx_Oracle.NotSupportedError: Python value cannot be converted to a database value

Это скриптЯ пытаюсь бежать.

src_conn = cx_Oracle.connect(username+'/'+password+'@'+database)
src_cursor=src_conn.cursor()
tgt_conn = cx_Oracle.connect(tgt_username+'/'+tgt_password+'@'+tgt_database)
tgt_cursor=tgt_conn.cursor()
for files in file_path:
    cols=[]
    col_id=[]
    file=files.replace("\n","")
    column_list_query="select COLUMN_NAME,COLUMN_ID from all_tab_columns where owner='GDW' and table_name ='"+file+"' order by column_id"
    col=src_cursor.execute(column_list_query)
    col_list=col.fetchall()

    for value in col_list:
        cols.append(value[0])
        col_id.append(":"+str(value[1]))

    col_names="("+','.join(cols)+")"
    col_ids="("+','.join(col_id)+")"

    insert_statement='INSERT INTO '+file+' '+col_names+' VALUES '+col_ids
    select_statment="SELECT * FROM "+file
    src_cursor.bindarraysize=1000
    src_values=src_cursor.execute(select_statment)
    print("Copy contents into table :"+file)


    def ResultIter(cursor, arraysize=500):
        while True:
            results = src_cursor.fetchmany(arraysize)
            if not results:
                break
            yield results

    tgt_cursor.prepare(insert_statement)
    for result in ResultIter(src_values):

        if not result:
            break
        tgt_cursor.executemany(None,result)
        tgt_conn.commit()

1 Ответ

0 голосов
/ 30 ноября 2018

О проблеме сообщили здесь , и вы можете посмотреть комментарии там.

Причина ошибки заключается в том, что в первом пакете один или несколько столбцов былиграниц всегда нет, но в следующем пакете один из этих столбцов теперь имеет значение.Это исправлено в исходном коде cx_Oracle, так что вы можете создать себя или подождать, пока будет выпущен релиз патча.

В противном случае текущие решения следующие:

(1) выполнитьвсе вставки в одном пакете (но в зависимости от размера это может быть невозможно)

(2) создать новый курсор для каждого пакета (чтобы cx_Oracle вычислял типы для каждого пакета)

(3) используйте cursor.setinputsizes () для указания типов и размеров (может быть громоздким)

Простой тестовый пример, демонстрирующий проблему, выглядит следующим образом:

import cx_Oracle

conn = cx_Oracle.connect("cx_Oracle/welcome")
cursor = conn.cursor()

cursor.execute("truncate table TestTempTable")

sql = "insert into TestTempTable values (:1, :2)"
cursor.executemany(sql, [(1, None), (2, None)])
cursor.executemany(sql, [(3, None), (4, "Testing")])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...