Неверное значение строки для закодированных символов - python вставить в мой sql - PullRequest
0 голосов
/ 01 марта 2020

Я разбираю форму отчета amazon, разбиваю строки на поля и затем создаю 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'])

Ответы [ 2 ]

1 голос
/ 01 марта 2020

Код пытается записать текст, закодированный как 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 сделает все просто.

0 голосов
/ 02 марта 2020

Клиент работает с кодировкой latin1 (92, et c). Таблица хотела бы иметь кодировку 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-острый и двойную точку? Или это просто начало какого-то другого беспорядка? Иногда несколько байтов подряд являются «плохими». Для дальнейшего анализа вашей ситуации, пожалуйста, получите гекс для более чем одного байта и / или укажите, какие символы, по вашему мнению, должны быть включены в текст .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...