无法使用cx-Oracle插入Unicode

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)

  • 我发现[当前页](http://www.oracle.com/technetwork/articles/tuininga-cx-oracle-084866.html),其具有码作为`os.environ [ "NLS_LANG"] =" .AL32UTF8" "这对我来说很有用.注意前导点但没有下划线. (5认同)