2013-02-28 93 views
2

我为制作字符编码问题表示歉意,因为我知道你们每天都会有很多人,但是我无法弄清楚我的问题,因此无论如何我都会问。使用正确的Python编码从Oracle导入使用正确的编码

这是我们正在做的:从Oracle数据库使用Python和cx_Oracle

  1. 取数据。
  2. 使用Python将数据写入文件。
  3. 使用Python和psycopg2将文件接收到Postgres中。

这里是重要的Oracle设置:

SQL> select * from NLS_DATABASE_PARAMETERS; 

PARAMETER      VALUE 
------------------------------ ---------------------------------------- 
NLS_LANGUAGE     AMERICAN 
NLS_TERRITORY     AMERICA 
NLS_CURRENCY     $ 
NLS_ISO_CURRENCY    AMERICA 
NLS_NUMERIC_CHARACTERS   ., 
NLS_CHARACTERSET    US7ASCII 

根据这一NLS_LANGfaq,你意思是根据你的客户端操作系统使用设置NLS_LANG。

运行locale给我们:LANG=en_US.UTF-8(所有其他字段也是en_US.UTF-8)。

所以,在我们的Python脚本,我们设置这样的:

os.environ["NLS_LANG"] = "AMERICAN_AMERICA.AL32UTF8"

然后我们导入数据,并将其写入文件。

row = cur.fetchall() 
fil.write(row[0][0]) #For this test, I am only writing one row and one field. 

我们将该文件导入到我们的UTF-8 Postgres数据库中。

不幸的是,出于某种原因,我们在我们的文件中获得了这个符号: 在后面的PG表中。如果我的理解是正确的,这是Replace Character。我相信如果Unicode不识别符号,那么字符就会显示出来。

(在某些文本编辑器中,符号显示为�)。

我不明白的是为什么会发生这种情况?我以为UTF-8向后兼容7位ASCII码?

即使我们正在使用区域页面,它不应该仍然有效,因为客户端正在使用美国和Oracle服务器正在使用AMERICAN?

如何检查数据是否正确导入,如果不正确,我如何解决它,以便将来进口?

注意:Oracle字段是CHAR字段,而不是NCHAR字段。注意2:我们使用的是Python 2.4,所以我们在Python 3.X中没有原生Unicode的东西。所以,虽然我认为cx_Oracle完全关心了这一点,但Python可能会在某处搞乱。

谢谢你的时间,我希望你有美好的一天。

回答

0

不幸的是,出于某种原因,我们在我们的文件中获得了这个符号:以及随后的PG表格。如果我的理解是正确的,那就是替换字符。我相信如果Unicode不识别符号,那么字符就会显示出来。

大部分是正确的,但不完全。当使用该编码时,PostgreSQL将拒绝插入非UTF8文本字符(在StackOverflow上搜索“无效的UTF8 postgresql”)。您看到的字符很可能是您的字体无法识别的有效UTF8字符,因此显示替换字符。如果符号在你的Oracle数据库中,并且实际上是那里的替换符号,那么你想用什么替换它?如果是这样的话,这些信息已经不存在了。

我不明白为什么会发生这种情况?我以为UTF-8向后兼容7位ASCII码?

它是。

如何检查数据是否正确导入,如果不正确,我如何解决这个问题以便将来导入?

您的问题很可能是Oracle数据库的上游。我会发现实际将问题数据插入到Oracle数据库中并在那里修复它。如果您可以检查Pg中的数据与Oracle中的数据,则应该能够确定数据是否与字符相同(并标记任何差异)。这就是如何检查你当前的进口。

注意2:我们使用的是Python 2.4,所以我们在Python 3.X中没有原生Unicode的东西。所以,虽然我认为cx_Oracle完全关心了这一点,但Python可能会在某处搞乱。

这是另一种可能性。我个人对文件转换更喜欢Perl,因为它集成了正则表达式和绝对最高的PostgreSQL支持。不过,我承认您的进口程序在此时可能不易兑换。我比Perl更熟悉Perl中的UTF8转换问题。不过,如果您可以检查以二进制格式显示这些符号的数据,我的确很奇怪。