我正在编写一个Python脚本,该脚本读取CSV并使用cx_Oracle将内容写入Oracle数据库。到目前为止,我遇到了以下错误:
UnicodeEncodeError: 'ascii' codec can't encode character '\xa0' in position 1369: ordinal not in range(128)
显然,cx_Oracle 正在尝试将 Unicode 字符转换为 ASCII,但它不起作用。
一些澄清点:
- 我使用的是 Python 3.4.3
- CSV 文件采用 UTF-8 编码,打开方式如下:
open('all.csv',encoding='utf8')
- 我在数据库中使用
NVARCHAR2
字段作为文本,并且NLS_NCHAR_CHARACTERSET
设置为AL16UTF16
。NLS_CHARACTERSET
是WE8MSWIN1252
,但据我了解,这应该不相关,因为我使用的是NVARCHAR2
。 - 我尝试将
NLS_LANG
环境变量设置为.AL16UTF16
、_.AL16UTF16
和AMERICAN_AMERICA.WE8MSWIN1252
每 this post ,但我仍然遇到同样的错误。
鉴于我正在读取 UTF-8 文件并尝试写入 Unicode 编码表,有人能想到为什么 cx_Oracle 仍会尝试将我的数据转换为 ASCII 吗?
我能够使用此代码产生错误:
field_map = {
...
}
with open('all.csv', encoding='utf8') as f:
reader = csv.DictReader(f)
out_rows = []
for row in reader:
if i == 1000:
break
out_row = {}
for field, source_field in field_map.items():
out_val = row[source_field]
out_row[field] = out_val
out_rows.append(out_row)
i += 1
out_db = datum.connect('oracle-stgeom://user:pass@db')
out_table = out_db['service_requests']
out_table.write(out_rows, chunk_size=10000)
datum
模块是我正在开发的一个数据抽象库。找到负责写入 Oracle 表的函数 here .
完整的回溯是:
File "C:\Projects\311\write.py", line 64, in <module>
out_table.write(out_rows, chunk_size=10000)
File "z:\datum\datum\table.py", line 89, in write
self._child.write(rows, from_srid=from_srid, chunk_size=chunk_size)
File "z:\datum\datum\oracle_stgeom\table.py", line 476, in write
self._c.executemany(None, val_rows)
UnicodeEncodeError: 'ascii' codec can't encode character '\xa0' in position 1361: ordinal not in range(128)
最佳答案
检查连接上“encoding”和“nencoding”属性的值。该值是通过调用检查环境变量 NLS_LANG 和 NLS_NCHAR 的 OCI 例程来设置的。看起来这个值是 US-ASCII 或等效值。当写入数据库时,cx_Oracle 获取文本并通过以 Oracle 客户端期望的编码进行编码来获取字节字符串。请注意,这与数据库编码无关。一般来说,为了获得最佳性能,最好匹配数据库和客户端编码 - 但如果不这样做,Oracle 会很乐意在两者之间进行转换,前提是所使用的所有字符都可以在两个字符集中表示!
请注意,如果 NLS_LANG 的值无效,则它实际上会被忽略。 AL16UTF16 就是这样一个无效条目!因此,将其设置为您想要的值(例如.AL32UTF8)并检查连接上的encoding和nencoding的值,直到获得您想要的值。
另请注意,除非另有说明,否则所有通过 cx_Oracle 绑定(bind)到数据库的字符串均假定采用正常编码,而不是 NCHAR 编码。您可以使用cursor.setinputsizes() 并指定输入类型为NCHAR、FIXED_NCHAR 或LONG_NCHAR 来覆盖此设置。
关于python - 无法使用 cx_Oracle 写入 Unicode 文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37574647/