У меня возникла проблема с вставкой Unicode в схему Oracle, я думаю, что база данных является экземпляром Oracle 11g, но на данный момент я не уверен. Я использую python 2.6.1 в OS X 10.6.8 (это системная версия python) и использую модуль драйвера cx-Oracle версии 5.1, загруженный с sourceforge.net, собранный и установленный в экземпляр virtualenv 1.6.1. с видимыми пакетами сайта. Мой сценарий выглядит следующим образом
import cx_Oracle
connection = cx_Oracle.connect(
"<name>/<password>@<host>/<service-name>"
)
cursor = connection.cursor()
result = cursor.execute(u"create table UNICODE_TEST (id NUMBER(6), text NCLOB not NULL)")
raw_text = open("test.txt",'r').read()
if isinstance(raw_text,str):
raw_text = raw_text.decode("utf_8")
statement = u"insert into UNICODE_TEST (id, text) values (1,'%s')" % raw_text
result = cursor.execute(statement)
Я создаю соединение, создаю курсор, выполняю статус для создания тестовой таблицы с идентификатором и текстовым полем типов NUMBER и NCLOB. Я открываю файл, содержащий текст, закодированный в UTF-8, и декодирую строку в Unicode. Создайте статус вставки в строке Unicode и выполните этот оператор, и результатом будет эта ошибка.
Traceback (most recent call last):
File "unicode-test.py", line 19, in <module>
result = cursor.execute(statement)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2122' in position 170: ordinal not in range(128)
Что-то пытается закодировать мой оператор как ASCII перед тем, как вставить его в схему Oracle. Поэтому я начал поиски, чтобы лучше понять, как cx-Oracle обрабатывает Unicode, и нашел это в HISTORY.txt исходного кода cx-Oracle, который я загрузил с sourceforge.net.
Изменения с 5.0.4 на 5.1
1) Убрать поддержку режима UNICODE и разрешить передачу Unicode в везде, где может быть передана строка. Это означает, что строки будут передается в Oracle с использованием значения среды NLS_LANG также переменная в Python 3.x. Это устранило кучу проблем. которые были обнаружены при использовании режима UNICODE, а также удалены ненужные ограничение в Python 2.x, что Unicode нельзя использовать в строках подключения или операторы SQL, например. ...
Я предполагаю, что для переменной среды NLS_LANG установлено значение ascii или какой-либо эквивалент, поэтому я пытаюсь установить для NLS_LANG значение AL32UTF8, которое, как я считаю, является правильным значением для Unicode, и устанавливаю новое значение перед созданием моего соединения.
os.environ["NLS_LANG"] = "AL32UTF8"
connection = cx_Oracle.connect(
"<user>/<password>@<host>/<service-name>"
)
cursor = connection.cursor()
...
Но я получаю эту ошибку.
Traceback (most recent call last):
File "unicode-test.py", line 11, in <module>
"<user>/<password>@<host>/<service-name>"
cx_Oracle.DatabaseError: ORA-12705: Cannot access NLS data files or invalid environment specified
Похоже, я не могу изменить значение NLS_LANG.
Вот мои вопросы на данный момент. Мне не хватает чего-то простого, например, неправильного типа столбца? Проблема с драйвером cx-Oracle? Нужно ли мне устанавливать переменную среды WITH_UNICODE при сборке модуля cx-Oracle, и как мне это сделать? Проблема с экземпляром Oracle? У меня мало опыта работы с Oracle, и я никогда не работал с Oracle и python вместе. Я потратил два дня на работу над этой проблемой и хотел бы лучше понять, в чем проблема, прежде чем я пойду в группу администраторов баз данных.
Благодарность,
1 ответ
Установка переменной окружения - правильный путь, но "AL32UTF8" - неправильное значение для NLS_LANG. Чтобы получить правильное значение NLS_LANG, используемого в вашем экземпляре Oracle, выполните
SELECT USERENV ('language') FROM DUAL
Похожие вопросы
Связанные вопросы
Новые вопросы
python
Python — это мультипарадигмальный многоцелевой язык программирования с динамической типизацией. Он предназначен для быстрого изучения, понимания и использования, а также обеспечивает чистый и унифицированный синтаксис. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Если у вас есть вопросы о версии Python, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas, NumPy) укажите это в тегах.
os.environ["NLS_LANG"] = ".AL32UTF8"
и это помогло мне. Обратите внимание на начальную точку, но без подчеркивания.