OracleDB Fetch from Select при обработке выходного типа CLOB вызывает сбой Python ⇐ Python
-
Anonymous
OracleDB Fetch from Select при обработке выходного типа CLOB вызывает сбой Python
Я использовал SQLAlchemy с OracleDB в качестве драйвера для создания своих приложений.
Я заметил, что один из процессов неожиданно завершился, находясь внутри блока исключений попытки, кроме.
И после проб и ошибок я нашел причину в обработчике, используемом для чтения данных из CLOB и BLOB в строку.
def output_type_handler(курсор, метаданные): если код метаданных.type_code равен oracledb.DB_TYPE_CLOB: вернуть курсор.var(oracledb.DB_TYPE_LONG, arraysize=cursor.arraysize) если метаданные.type_code — oracledb.DB_TYPE_BLOB: вернуть курсор.var(oracledb.DB_TYPE_LONG_RAW, arraysize=cursor.arraysize) если код метаданных.type_code равен oracledb.DB_TYPE_NCLOB: вернуть курсор.var(oracledb.DB_TYPE_LONG_NVARCHAR, arraysize=cursor.arraysize) Я попробовал использовать только OracleDB без SqlAlchemy, успешно получил данные и прочитал CLOB с помощью read().
Однако после того, как я включил обработчик выходного типа, даже fetchone() вызывает сбой Jupyter с кодом выхода: 3221225477.
Я пробовал другие настройки, например oracledb.defaults.fetch_lobs = False, и это также вызвало ту же проблему.
Есть ли какие-либо конфигурации, которые я могу использовать с SQLAlchemy, чтобы это исправить?
Изменить: я обнаружил, что проблема возникает при доступе к таблице с несколькими столбцами CLOB через DBLink. Без DBLink работает нормально.
Версия БД: 19.6c Версия клиента: 21c Питон: 3.9.5 оракулб: 1.4.2 SQLАлхимия: 2.0.23 Тип подключения: толстый режим
Схема таблицы:
CREATE TABLE AUTOMAIL_JOB_LIST ( ИДЕНТИФИКАЦИОННЫЙ НОМЕР, Сгенерированный ПО УМОЛЧАНИЮ НА НУЛЕ, КАК ИДЕНТИФИКАЦИЯ НАЧИНАЕТСЯ С 1, УВЕЛИЧИВАЕТСЯ НА 1, НОМЕР ИД_ОПРЕДЕЛЕНИЯ, SERVICE_GROUP VARCHAR2 (100 символов), ТЕМА VARCHAR2 (300 символов), EMAIL_CONTENT CLOB, ПРИЛОЖЕНИЕ КЛОБ, ОТПРАВИТЬ_ТО CLOB, SEND_CC CLOB, SEND_BCC CLOB, НОМЕР СОСТОЯНИЯ(2) ПО УМОЛЧАНИЮ 0, CREATE_DATE ДАТА ПО УМОЛЧАНИЮ SYSDATE, SEND_DATE ДАТА ПО УМОЛЧАНИЮ NULL, OWNER_EMAIL VARCHAR2(200 СИМВОЛОВ)) В таблице хранятся электронные письма для отправки. Столбцы Attachment, send_to, send_cc и send_bcc обычно представляют собой всего лишь несколько путей к электронной почте/файлу. Проблема возникла из-за столбца EMAIL_CONTENT, в котором хранится весь HTML-код электронного письма, который может содержать таблицы.
Извлечь их все, кроме EMAIL_CONTENT, а затем только EMAIL_CONTENT, это нормально, но при нажатии SELECT * могут возникнуть проблемы.
Пример кода:
из импорта sqlalchemy create_engine импортировать панд как pd engine = create_engine("", connect_args = { "кодировка": "UTF-16", "нэнкодирование": "UTF-16" }, толщиной_режим = Правда, Pool_pre_ping = Правда, echo_pool = Правда, размер_пула = 0) запрос = """ ВЫБИРАТЬ * ОТ AUTOMAIL_JOB_LIST@DBLINK """ df = pd.read_sql(запрос, механизм) Версия OracleDB-Python:
импортировать oracledb импортировать панд как pd oracledb.init_oracle_client() def output_type_handler (курсор, метаданные): если код метаданных.type_code равен oracledb.DB_TYPE_CLOB: вернуть курсор.var(oracledb.DB_TYPE_LONG, arraysize=cursor.arraysize) если метаданные.type_code — oracledb.DB_TYPE_BLOB: вернуть курсор.var(oracledb.DB_TYPE_LONG_RAW, arraysize=cursor.arraysize) если код метаданных.type_code равен oracledb.DB_TYPE_NCLOB: вернуть курсор.var(oracledb.DB_TYPE_LONG_NVARCHAR, arraysize=cursor.arraysize) запрос = """ ВЫБИРАТЬ * ОТ AUTOMAIL_JOB_LIST@DBLINK """ oracle_connection_string = oracledb.madesn(oracle_host, oracle_port, service_name = oracle_service_name) oracle_connection = oracledb.connect (пользователь = oracle_username, пароль = oracle_password, dsn = oracle_connection_string, кодировка = «UTF-16», nencoding = «UTF-16») oracle_connection.outputtypehandler = выходной_тип_обработчик df = pd.read_sql(запрос, oracle_connection) # курсор = oracle_connection.cursor() # курсор.execute(запрос) # строка = курсор.fetchone()
Я использовал SQLAlchemy с OracleDB в качестве драйвера для создания своих приложений.
Я заметил, что один из процессов неожиданно завершился, находясь внутри блока исключений попытки, кроме.
И после проб и ошибок я нашел причину в обработчике, используемом для чтения данных из CLOB и BLOB в строку.
def output_type_handler(курсор, метаданные): если код метаданных.type_code равен oracledb.DB_TYPE_CLOB: вернуть курсор.var(oracledb.DB_TYPE_LONG, arraysize=cursor.arraysize) если метаданные.type_code — oracledb.DB_TYPE_BLOB: вернуть курсор.var(oracledb.DB_TYPE_LONG_RAW, arraysize=cursor.arraysize) если код метаданных.type_code равен oracledb.DB_TYPE_NCLOB: вернуть курсор.var(oracledb.DB_TYPE_LONG_NVARCHAR, arraysize=cursor.arraysize) Я попробовал использовать только OracleDB без SqlAlchemy, успешно получил данные и прочитал CLOB с помощью read().
Однако после того, как я включил обработчик выходного типа, даже fetchone() вызывает сбой Jupyter с кодом выхода: 3221225477.
Я пробовал другие настройки, например oracledb.defaults.fetch_lobs = False, и это также вызвало ту же проблему.
Есть ли какие-либо конфигурации, которые я могу использовать с SQLAlchemy, чтобы это исправить?
Изменить: я обнаружил, что проблема возникает при доступе к таблице с несколькими столбцами CLOB через DBLink. Без DBLink работает нормально.
Версия БД: 19.6c Версия клиента: 21c Питон: 3.9.5 оракулб: 1.4.2 SQLАлхимия: 2.0.23 Тип подключения: толстый режим
Схема таблицы:
CREATE TABLE AUTOMAIL_JOB_LIST ( ИДЕНТИФИКАЦИОННЫЙ НОМЕР, Сгенерированный ПО УМОЛЧАНИЮ НА НУЛЕ, КАК ИДЕНТИФИКАЦИЯ НАЧИНАЕТСЯ С 1, УВЕЛИЧИВАЕТСЯ НА 1, НОМЕР ИД_ОПРЕДЕЛЕНИЯ, SERVICE_GROUP VARCHAR2 (100 символов), ТЕМА VARCHAR2 (300 символов), EMAIL_CONTENT CLOB, ПРИЛОЖЕНИЕ КЛОБ, ОТПРАВИТЬ_ТО CLOB, SEND_CC CLOB, SEND_BCC CLOB, НОМЕР СОСТОЯНИЯ(2) ПО УМОЛЧАНИЮ 0, CREATE_DATE ДАТА ПО УМОЛЧАНИЮ SYSDATE, SEND_DATE ДАТА ПО УМОЛЧАНИЮ NULL, OWNER_EMAIL VARCHAR2(200 СИМВОЛОВ)) В таблице хранятся электронные письма для отправки. Столбцы Attachment, send_to, send_cc и send_bcc обычно представляют собой всего лишь несколько путей к электронной почте/файлу. Проблема возникла из-за столбца EMAIL_CONTENT, в котором хранится весь HTML-код электронного письма, который может содержать таблицы.
Извлечь их все, кроме EMAIL_CONTENT, а затем только EMAIL_CONTENT, это нормально, но при нажатии SELECT * могут возникнуть проблемы.
Пример кода:
из импорта sqlalchemy create_engine импортировать панд как pd engine = create_engine("", connect_args = { "кодировка": "UTF-16", "нэнкодирование": "UTF-16" }, толщиной_режим = Правда, Pool_pre_ping = Правда, echo_pool = Правда, размер_пула = 0) запрос = """ ВЫБИРАТЬ * ОТ AUTOMAIL_JOB_LIST@DBLINK """ df = pd.read_sql(запрос, механизм) Версия OracleDB-Python:
импортировать oracledb импортировать панд как pd oracledb.init_oracle_client() def output_type_handler (курсор, метаданные): если код метаданных.type_code равен oracledb.DB_TYPE_CLOB: вернуть курсор.var(oracledb.DB_TYPE_LONG, arraysize=cursor.arraysize) если метаданные.type_code — oracledb.DB_TYPE_BLOB: вернуть курсор.var(oracledb.DB_TYPE_LONG_RAW, arraysize=cursor.arraysize) если код метаданных.type_code равен oracledb.DB_TYPE_NCLOB: вернуть курсор.var(oracledb.DB_TYPE_LONG_NVARCHAR, arraysize=cursor.arraysize) запрос = """ ВЫБИРАТЬ * ОТ AUTOMAIL_JOB_LIST@DBLINK """ oracle_connection_string = oracledb.madesn(oracle_host, oracle_port, service_name = oracle_service_name) oracle_connection = oracledb.connect (пользователь = oracle_username, пароль = oracle_password, dsn = oracle_connection_string, кодировка = «UTF-16», nencoding = «UTF-16») oracle_connection.outputtypehandler = выходной_тип_обработчик df = pd.read_sql(запрос, oracle_connection) # курсор = oracle_connection.cursor() # курсор.execute(запрос) # строка = курсор.fetchone()
Мобильная версия