【问题标题】:Incorrect String Value for encoded characters - python insert in to my sql编码字符的字符串值不正确 - python 插入到我的 sql
【发布时间】:2020-06-13 18:41:44
【问题描述】:

我正在解析亚马逊的报告表单,将行拆分为字段,然后创建 mysql 上传。我相信的数据最初是 iso-8859-1。除非数据中有一些特殊字符,如 Ä 或 ®,否则数据可以正常上传到 mysql。如果发生这种情况,我会收到类似pymysql.err.InternalError: (1366, "Incorrect string value: '\\xAE Kids...' for column 'item-name' at row 74")TypeError: can only concatenate str (not "bytearray") to str 的错误。我可以通过替换字节来解决它,但我不想建立一个巨大的列表,而且我真的想存储正确的值。我尝试更改我的 mysql 字符集和排序规则,但这似乎没有解决。我觉得修复是一个简单的修复,但我已经尝试了几个小时。

report_as_dict = report.parsed
report_as_dict = report_as_dict.replace(b' \r\n', b'\r\n')  # remove black space at end

 multi_line_rebuild=list()
    for line in line_split[1:]:
        field_split = line.split(b'\t')
        logger.debug('Field Split : %s', field_split)
        field_split = [x.replace(b'\x92', b'') for x in field_split]  # removes single quotes
        field_split = [x.replace(b'\xA0', b'') for x in field_split]  # removes (
        field_split = [x.replace(b'\xAE', b'') for x in field_split]  # removes @
        field_split = [x.replace(b'\xCD', b'l') for x in field_split]  # replaces l with ' with l
        field_split = [x.replace(b'\xE4', b'a') for x in field_split]  # replaces a with two dots with a

        multi_line_rebuild.append(field_split)

 ....


 run_query_with_warnings(query_string, field_split=multi_line_rebuild)

功能

def run_query_with_warnings(warn_type, query_string, **kargs):

db = MySQLdb.connect(host=cred.host, user=cred.user, password=cred.password, db=cred.db, port=cred.port)
cursor = db.cursor()
cursor.executemany(query_string, kargs['field_split'])

【问题讨论】:

  • 每张表都是utf8 / utf8_general_ci

标签: python mysql utf-8


【解决方案1】:

客户端正在使用 latin1 编码(92 等)。该表希望该“右单引号”具有 utf8 编码 (E28099)。您可以通过告诉 MySQL 客户端在连接参数中使用 latin1 并将列设置为 utf8(或 utf8mb4)来实现这一点。

前者有点像

db = MySQLdb.connect(host=DB_HOST, user=DB_USER, passwd=DB_PASS, db=DB_NAME,
              charset="utf8", use_unicode=True)

还要检查是否应该将源代码的开头更改为

# -*- coding: utf-8 -*-

但是……我很担心。你真的在使用正确的引号、注册符号 (AE)、I-acute 和 a-double-dot 吗?或者这仅仅是其他混乱的开始?有时连续的多个字节是“坏的”。为了进一步分析您的情况,请获取不止一个字节的十六进制,和/或提供您认为文本应该包含的字符。

【讨论】:

    【解决方案2】:

    代码正在尝试将编码为 ISO-8859-1 的文本写入设置为期望 UTF-8 的表中。

    有两种解决方案:

    • 将连接上的charset 参数设置为latin1(这与ISO-8859-1 相同)并让连接处理将字节重新编码为UTF-8

      db = MySQLdb.connect(host=cred.host, user=cred.user, password=cred.password, 
                           db=cred.db, port=cred.port, charset='latin1')
      
    • 将编码字节解码为str 并让连接执行编码。

      report_as_dict = report.parsed.decode('ISO-8859-1')
      

    如果代码除了将字节直接写入数据库之外什么都不做,那么第一个选项就可以了;如果字节正在进行进一步的操作,那么解码为str 将使事情变得简单。

    【讨论】:

    • 谢谢...如果我的所有数据都是 ISO-8859-1,那么更改表的数据类型是否有意义?
    • @personalt UTF-8 支持所有 unicode 代码点,而 ISO-8859-1 仅支持其中的 256 个,所以总的来说我倾向于坚持使用 UTF-8。另一方面,如果你知道你的数据编码永远不会改变,那么改变表的编码可能是值得的。
    猜你喜欢
    • 1970-01-01
    • 2011-08-20
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-04
    相关资源
    最近更新 更多