如何修复python硬编码字典编码问题

时间:2017-02-15 19:16:15

标签: python mysql encoding

错误:

pymysql.err.InternalError: (1366, "Incorrect string value: '\\xEF\\xBF\\xBD 20...' for column 'history' at row 1")

我收到了一些这方面的变化,因为我试图调整我的字典,总是在历史专栏中,唯一的变化是它告诉我的字符是问题。

我无法发布字典,因为它有敏感信息,但这里是jist:

  • 我开始使用所需的200个地址(包括州,邮政编码等) 为DB插入进行验证,规范化和标准化。
  • 我花了很多时间在谷歌地图上进行验证和标准化。
  • 我决定变得喜欢,并把所有疯狂的重音字母放在这些世界地址的地址(通常是谷歌的副本,因为我不知道如何输入和A与o在它上面,哈哈),新加坡到巴西,无处不在。
  • 我在处理后的字典中最终得到了120个唯一的地址。
  • 在SQLite中输入数据并输出到CSV时,一切都完美无缺。问题完全在于MySQL和一些偷偷摸摸的不可见角色。

注意:我使用this删除了7小时复制/粘贴到记事本后的重音符号,使用notepad ++对其进行编码,并尝试以一种使其完全正确编码的方式处理数据。我想我确实失去了带有重音的版本,现在只输出这个工具。

我在字典中看不到“\ xEF \ xBF \ xBD 20 ......”我只看到文字。目前我甚至没有看到“20”......这两个字符帮我找到了以前的问题。

我可以展示代码:

def insert_tables(cursor, assets_final, ips_final):
    #Insert Asset data into asset table
    field_names_dict = get_asset_field_names(assets_final)
    sql_field_names = ",".join(field_names_dict.keys())
    for key, row in assets_final.items():
        insert_sql = 'INSERT INTO asset(' + sql_field_names + ') VALUES ("' + '","'.join(field_value.replace('"', "'") for field_value in list(row.values())) + '")'
        print(insert_sql)
        cursor.execute(insert_sql)

    #Insert IP data into IP table
    field_names_dict = get_ip_field_names(ips_final)
    sql_field_names = ",".join(field_names_dict.keys())
    for hostname_key, ip_dict in ips_final.items():
        for ip_key, ip_row in ip_dict.items():
            insert_sql = 'INSERT INTO ip(' + sql_field_names + ') VALUES ("' + '","'.join(field_value.replace('"', "'") for field_value in list(ip_row.values())) + '")'
            print(insert_sql)
            cursor.execute(insert_sql)

def output_sqlite_db(sqlite_file, assets_final, ips_final):
    conn = sqlite3.connect(sqlite_file)
    cursor = conn.cursor()
    insert_tables(cursor, assets_final, ips_final)
    conn.commit()
    conn.close()

def output_mysql_db(assets_final, ips_final):
    conn = mysql.connect(host=config.mysql_ip, port=config.mysql_port, user=config.mysql_user, password=config.mysql_password, charset="utf8mb4", use_unicode=True)
    cursor = conn.cursor()
    cursor.execute('USE ' + config.mysql_DB)
    insert_tables(cursor, assets_final, ips_final)
    conn.commit()
    conn.close()
编辑:这可能与我使用Cygwin作为我的终端的事实有关吗?哈!我添加了这一行并得到了另一条消息(现在再次使用重音版本):

cursor.execute('SET NAMES utf8')

错误:

pymysql.err.InternalError: (1366, "Incorrect string value: '\\xC5\\x81A II...' for column 'history' at row 1")

1 个答案:

答案 0 :(得分:1)

我可以对你提供的消息有所了解:

案例1:

>>> import unicodedata as ucd
>>> s1 = b"\xEF\xBF\xBD"
>>> s1
b'\xef\xbf\xbd'
>>> u1 = s1.decode('utf8')
>>> u1
'\ufffd'
>>> ucd.name(u1)
'REPLACEMENT CHARACTER'
>>>

看起来你已经获得了一些用utf8以外的编码编码的字节(例如cp1252),然后尝试了bytes.decode(encoding='utf8', errors='strict')。这检测到一些错误。然后再次使用errors =&#34进行解码;替换"。这没有例外。但是,您的数据已将错误字节替换为替换字符(U + FFFD)。然后使用str.encode对数据进行编码,以便可以写入文件或数据库。每个替换字符变为3个十六进制字节EF BF BD

......更多信息

案例2:

>>> s2 = b"\xC5\x81A II"
>>> s2
b'\xc5\x81A II'
>>> u2 = s2.decode('utf8')
>>> u2
'\u0141A II'
>>> ucd.name(u2[0])
'LATIN CAPITAL LETTER L WITH STROKE'
>>>