python - 无法使用 cx-Oracle 插入 Unicode

标签 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)

我创建了一个连接,创建了游标,执行了一个语句来创建一个带有 NUMBER 和 NCLOB 类型的 id 和文本字段的测试表。 我打开一个文件,其中包含我知道的以 UTF-8 编码的文本,将字符串解码为 un​​icode。 在 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 中找到了这一点

Changes from 5.0.4 to 5.1
1) Remove support for UNICODE mode and permit Unicode to be passed through in everywhere a string may be passed in. This means that strings will be passed through to Oracle using the value of the NLS_LANG environment variable in Python 3.x as well. Doing this eliminated a bunch of problems that were discovered by using UNICODE mode and also removed an unnecessary restriction in Python 2.x that Unicode could not be used in connect strings or SQL statements, for example. ...

我的假设是 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 小组之前更好地了解问题所在。

谢谢,

最佳答案

设置环境变量是正确的方法,但“AL32UTF8”不是 NLS_LANG 的正确值。要获得在您的 Oracle 实例中使用的 NLS_LANG 的正确值,请执行

SELECT USERENV ('language') FROM DUAL  

关于python - 无法使用 cx-Oracle 插入 Unicode,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14238824/

相关文章:

python - Pandas 将上一时期的数据设置为新的 DataFrame 列

sql - 在我的情况下,如何在 Oracle 中编写 SQL?

c++ - 从 C++ 中的 unicode 字符串检测语言环境

C# web服务,MySql编码问题

Python mysqldb 错误关闭连接

python - 如何有条件地使 python 的 argparse 模块需要额外的参数

python - tensorflow如何忽略未定义的标志

sql - 规范化 ORACLE 11g 中的列名

sql - 在团队中使用 Oracle 存储过程的工具?

html - 关于晦涩难懂的希腊字符的 Unicode/HTML 问题