sna*_*e77 17 python oracle unicode cx-oracle
我在将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)
Run Code Online (Sandbox Code Playgroud)
我创建一个连接,创建游标,执行一个语句来创建一个测试表,其中包含NUMBER和NCLOB类型的id和text字段.我打开一个文件,其中包含我所知道的以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)
Run Code Online (Sandbox Code Playgroud)
在将语句插入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()
...
Run Code Online (Sandbox Code Playgroud)
但是我得到了这个错误.
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
Run Code Online (Sandbox Code Playgroud)
所以看起来我无法篡改NLS_LANG值.
这是我现在的问题.我错过了一些简单的列类型吗?问题是cx-Oracle驱动程序?构建cx-Oracle模块时是否需要设置"WITH_UNICODE"环境变量?我该怎么做?问题是Oracle实例吗?我对Oracle没什么经验,也从未使用过Oracle和python.我花了两天时间研究这个问题,并希望在进入DBA小组之前更好地了解问题所在.
谢谢,
小智 15
设置环境变量是正确的方法,但"AL32UTF8"不是NLS_LANG的正确值.要获得在Oracle实例中使用的NLS_LANG的正确值,请执行
SELECT USERENV ('language') FROM DUAL
Run Code Online (Sandbox Code Playgroud)