Вставка ответа API Unicode, содержащего смайлики, в Mysql с использованием Python mysql.connector - PullRequest
0 голосов
/ 08 мая 2019

Я подключаюсь к API Graph Facebook, используя Python, и ответ curl доставляет кучу данных в формате Unicode.Я пытаюсь вставить эти данные в базу данных mysql с помощью драйвера python mysql.connector, но продолжаю сталкиваться с ошибками кодирования.

В частности, я получаю этот тип ошибки:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 40: ordinal not in range(128)
или
File "/Library/Python/2.7/site-packages/mysql/connector/cursor_cext.py", line 243, in execute raise errors.ProgrammingError(str(err)) mysql.connector.errors.ProgrammingError: 'ascii' codec can't encode character u'\xa0' in position 519: ordinal not in range(128)

Все поля моей базы данных - utf8mb4, и я считаю моя кодировка также UTF8.Так что я не могу понять, почему я получаю ошибки ASCII.

Ошибка происходит в поле «заголовок» возвращаемых постов в Instagram, которое включает в себя смайлики, так что я на 99% уверен, что это проблемапри комментировании этой строки все остальное работает как положено.

До сих пор я пытался:

Добавление use_unicode=True, charset='utf8' в команду mysql.connector.connect (согласно документации этопо умолчанию в любом случае)

Добавление #!/usr/bin/python # encoding=utf8 в начало скрипта

Добавление use_unicode=True, charset='ascii' в команду mysql.connector.connect, потому что почему бы не попробовать

Пробные комбинацииcaption.decode('utf') caption.encode('utf8') в переменной перед директивой вставки mysql.

Я не могу найти никакой ссылки на ASCII в документации по mysql.connector, поэтому я не уверен, почему он пытается выполнить преобразование.

В отношении второй ошибки, приведенной выше, при переходе к этой строке cursor_cext.py в пакете mysql.connector строки выглядят так:

try:
    if isunicode(operation):
        stmt = operation.encode(self._cnx.python_charset)
    else:
        stmt = operation
except (UnicodeDecodeError, UnicodeEncodeError) as err:
    raise errors.ProgrammingError(str(err))

Ранее я делал нечто подобноес PHP, успешно использующим старый API Instagram, но теперь, когда они изменились на API Graph Facebook для Instagram, я решил использовать Python, поскольку это выглядело проще, но теперь я не знаю, куда идти с этими ошибками.

1 Ответ

1 голос
/ 08 мая 2019

Когда вы объединяете строки Unicode и байтов в Python 2 (например, "a" + u"a"), существует неявное принуждение, вызывающее .decode() в строке байтов ("a"). Кодек по умолчанию для этого метода - ASCII в Python 2.

Ошибки кодирования, которые происходят во время неявного принуждения, могут быть довольно сложно отследить. В Python 3 неявное принуждение отсутствует, поэтому и код пользователя, и код библиотеки вынуждены хранить str и bytes отдельно.

Я предлагаю вам перейти на Python 3, если можете. Это может не сразу заставить ваш код работать, но, скорее всего, вы узнаете, где явно установить кодировку.

...