【发布时间】:2018-04-26 04:56:00
【问题描述】:
我正在尝试使用响应库从 Web 服务中检索 xml 字节字符串形式的响应,使用内存中的 XSLT 对其进行解析,然后使用 pyodbc 将输出写入 Teradata。我正在使用 python 3。
任何超出标准 ascii 127 代码点的字母都以两个字符的形式出现。例如 ü 作为 ü 进入数据库。
' 以 â 的形式出现,其后有两个不可打印的字符(PAD 和 SGCI,根据 notepad++)
响应中也有可能是汉字。
我的代码:
cnxn.pyodbc.connect('mydsn')
cnxn.setdecoding(pyodbc.SQL_CHAR, encoding='utf-8')
cnxn.setdecoding(pyodbc.SQL_WCHAR, encoding='utf-8')
cnxn.setdecoding(pyodbc.SQL_WMETADATA, encoding='utf-8')
cnxn.setencoding(encoding='utf-8')
cursor = cnxn.cursor()
transform = etree.XSLT(etree.fromstring(xsltasstring))
p = etree.XML(response.content)
result_tree = transform(p)
linefeed = '\n'
recordseperator = ','
output_list = str(result_tree).split(linefeed)
insert_sql = 'insert into the_table(.....)'
for item in output_list:
temp_list = item.split(recordseperator)
final_list.append(temp_list)
print(item)
print(item.encode())
cursor.executemany(insert_sql,final_list)
当我查看数据库时,一个示例字符串:ação 已被翻译为 ação
在循环中,
print(item) outputs correctly: ação`
print(final_list) also looks correct: ação
print(item.encode()) outputs b'a\xc3\xa7\xc3\xa3o'
c3,a7,c3,x3 corresponds to çã。我不明白是什么原因造成的,或者如何解决它。
我本来希望看到类似:b'a\xe7\xe3o'
根据 odbc 跟踪,我确实看到那些代码点 c3、a7 和 x3 被传递到缓冲区。
来自 Web 服务的响应确实有 UTF-8 编码声明,并且 Web 服务供应商还说响应编码是 UTF-8.
【问题讨论】:
-
您需要将您放入数据库的字符串从ascii转换为utf-8
-
@Fire 你说 ascii 时是指 Latin-1 吗?
-
正如我在您之前的帖子中所说,字节字符串
b'a\xe7\xe3o'是“ação”的Latin-1 编码。 UTF-8 编码为b'a\xc3\xa7\xc3\xa3o'。不要将 Unicode 代码点(U+E7表示“ç”)与其物理编码的字节值(C3 A7表示 UTF-8)混淆。 -
如果您将 UTF-8 编码的字节字符串
b'a\xc3\xa7\xc3\xa3o'当作拉丁语 1 对待(即解码),您会得到“çã”。这是因为您在 Latin-1 中具有 1:1 的代码点和字节值对应关系——但您只能获得 120k Unicode 字符中的前 256 个。 -
换句话说:
item中的内容似乎是正确的。如果数据库通信出现问题,您需要展示一个将条目插入数据库然后从数据库中获取的示例。