我在将 unicode 插入 Oracle 架构时遇到问题,我认为数据库是 Oracle 11g 实例,但目前还不确定。我在 OS X 10.6.8 上使用 python 2.6.1(这是 python 的系统版本)并使用从 sourceforge.net 下载的 cx-Oracle 驱动程序模块版本 5.1,构建并安装到 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 类型的 id 和文本字段。我打开一个文件,其中包含我知道的以 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)
在将我的语句插入 Oracle 模式之前,有些东西试图将其编码为 ASCII。所以我开始四处寻找以更好地了解 cx-Oracle 如何处理 unicode,并在我从 sourceforge.net 下载的 cx-Oracle 源代码的 HISTORY.txt 中找到了这一点
从 5.0.4 到 5.1 的更改
1) 删除对 UNICODE 模式的支持,并允许在任何可能传入字符串的地方传递 Unicode。这意味着字符串将使用 Python 中的 NLS_LANG 环境变量的值传递给 Oracle 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 驱动程序的问题吗?在构建 cx-Oracle 模块时,我是否需要设置“WITH_UNICODE”环境变量,我该怎么做?是 Oracle 实例的问题吗?我对 Oracle 的经验很少,也从未与 Oracle 和 python 一起工作过。我花了两天时间来解决这个问题,并希望在我去 DBA 小组之前更好地了解这个问题是什么。
谢谢,