【问题标题】:UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 54: ordinal not in range(128)UnicodeEncodeError:“ascii”编解码器无法在位置 54 编码字符 u'\xe9':序数不在范围内(128)
【发布时间】:2016-09-05 06:05:19
【问题描述】:

我知道,已经问了好几次了,但没有一个答案给我解决方案

这里是代码(Python 2.7):

import cx_Oracle
import pandas as pd

connstr = 'MyConstr'
conn = cx_Oracle.connect(connstr)
cur = conn.cursor()

xl = pd.ExcelFile("C:\\TEMP\\for_kkod.xlsx")
df = xl.parse(0)

for i in df.index:
    s = u"insert into MY_TABLE values({0}, '{1}')".format(int(df.iloc[i]['kkod']), df.iloc[i]['kkodnev'])
    print s
    print type(s)
    cur.execute(s)

两次打印的结果是这样的:

insert into MY_TABLE values(10, 'Készítés')
<type 'unicode'>

如您所见,s 的类型是 unicode,但我仍然收到以下错误消息:

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 54: ordinal not in range(128)

我尝试过使用和不使用 u"",使用和不使用所有可能的方式进行编码和解码,但仍然出现相同的错误消息

有什么想法吗?

【问题讨论】:

  • 你得到一个 encode 错误,因为cur.execute() 需要一个字节串。
  • 是的,但我的第一次尝试是这样的:cur.execute("insert into MYTABLE values(%s, %s)", (int(df.iloc[i]['kkod']) , df.iloc[i]['kkodnev']))

标签: python python-2.7 cx-oracle python-unicode


【解决方案1】:

您正在向cursor.execute() 提供Unicode SQL 语句。该方法只能采用 bytestring SQL 语句

您不应使用字符串插值将 Unicode 值插入 SQL 查询(其本身只是 ASCII)。始终使用查询参数!

 s = "insert into MY_TABLE values(:0, :1)"
 cur.execute(s, (int(df.iloc[i]['kkod']), df.iloc[i]['kkodnev']))

现在要插入的值作为参数传入,由数据库适配器负责编码这些正确性(以及正确转义值以规避 SQL 注入问题)。

上面使用编号(位置)参数,您也可以使用命名参数,将值传入字典中并匹配键:

 s = "insert into MY_TABLE values(:kkod, :kkodnev)"
 cur.execute(s, {'kkod': int(df.iloc[i]['kkod']), 'kkodnev': df.iloc[i]['kkodnev']})

您必须确保您的连接和表格列都正确配置为处理 Unicode。例如,您必须设置 NLS_LANG 选项:

import os
os.environ['NLS_LANG'] = '.AL32UTF8'

【讨论】:

  • 还是不行。我有这个: s = "insert into MYTABLE values(:kkod, :kkodnev)" print type(s) is: and the exec: cur.execute(s, {'kkod': int(df .iloc[i]['kkod']), 'kkodnev': df.iloc[i]['kkodnev']}),但同样的错误信息:UnicodeEncodeError: 'ascii' codec can't encode character u'\ xe9' 在第 11 位:序数不在范围内(128)
  • @Gabor:首先,100% 确定回溯包含cursor.execute() 行。也许将参数字典定义移动到单独的行(params = {'kkod': int(df.iloc[i]['kkod']), 'kkodnev': df.iloc[i]['kkodnev']}cur.execute(s, params)),并验证回溯是否仍归咎于cur.execute() 调用。然后验证您的数据库列是存储 Unicode 的正确类型,例如NVARCHAR2NLS_LANG 为您设置了什么?
  • Traceback(最近一次调用最后):文件“oracle_insert.py”,第 15 行,在 cur.execute(s, {'kkod': int(df.iloc[i][ 'kkod']), 'kkodnev': df.iloc[i]['kkodnev']}) UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 11: ordinal not in range(128)
  • 与此处相同: Traceback(最近一次调用最后一次):文件“oracle_insert.py”,第 17 行,在 cur.execute(s, params) UnicodeEncodeError: 'ascii' codec can' t 在位置 11 编码字符 u'\xe9':序数不在范围内(128)
  • 我明白了!我忘记在我的代码中输入以下行(如您所建议的)os.environ['NLS_LANG'] = '.AL32UTF8'。现在它在那里并且正在工作!非常感谢!
【解决方案2】:

只需使用以下参数进行连接:

connection = cx_Oracle.connect(connectString, encoding="UTF-8",nencoding="UTF-8")

【讨论】:

    猜你喜欢
    • 2013-02-11
    • 2013-11-18
    • 2015-02-10
    • 2017-09-01
    • 2016-08-26
    • 2017-03-29
    • 2011-07-05
    • 2018-07-10
    • 2012-04-14
    相关资源
    最近更新 更多