Msgstr "Неверное строковое значение: '\\ xD8 \\ xB9 \\ xD8 \\ xB1 \\ xD8 \\ xA8 ...' для столбца 'суп' в строке 1". можно отфильтровать 4 байта utf-8 символов? - PullRequest
0 голосов
/ 07 марта 2020

Я пытаюсь вставить очищенные HTML данные в MySQL базу данных, используя Python и SQLAlchemy.

Я получаю эту ошибку снова и снова в различных точках моего сценария очистки и сохранения:

sqlalchemy.exc.OperationalError: (_mysql_exceptions.OperationalError) (1366, "Incorrect string value: '\\xD8\\xB9\\xD8\\xB1\\xD8\\xA8...' for column 'soup' at row 1")

Теперь мое исследование этой темы c (спасибо StackOverflow) говорит мне, что я не могу добавить 4-байтовые символы UTF-8 в мою MySQL базу данных , если я не установлю символ кодирование в utf8mb4.

Ну, я сделал это. И это не сработало; Я все еще получаю ошибку. Смотрите мое заявление sqlalchemy.create_engine здесь:

from sqlalchemy import create_engine

engine = create_engine('mysql://username:password@localhost:3306/databaseName?charset=utf8mb4', echo=False)

Я даже вошел в MySQL, отбросил базу данных и переделал ее. Я все еще получаю сообщение об ошибке.

Так кто-нибудь знает (а), как я могу отфильтровать 4-байтовые символы UTF-8 из строки, используя Python3? или (b) как я могу заставить мою MySQL базу данных принимать 4-байтовые символы UTF-8?

re: фильтруя 4-байтовые символы UTF-8, я изменил что-то, найденное в StackOverflow, так:

filtered_x = ''.join(char for char in x if len(char.encode('utf-8')) < 3) (по этой ссылке )

но, ну, это не сработало! Согласно сообщению об ошибке, проблема с "супом столбца". Итак, я сделал это:

            filtered_soup = ''.join(char for char in the_page_soup if len(char.encode('utf-8', errors="ignore")) < 4)
            page_to_add = SqlPage(what=query_obj.query,
                                  where=query_obj.city,
                                  url=query_obj.soups[key].page_url,
                                  soup=filtered_soup)

Но я все еще получаю ошибку. Что дает? (Я изменил len(char.encode('utf-8', errors="ignore")) < 3 на < 4, но я подумал, что это имеет смысл ... Я пытаюсь удалить 4-байтовые символы и 4 < 4 == false, плюс сообщение об ошибке также происходит с < 3.)

Помогите, пожалуйста!

Редактировать: эта тема имеет несколько хороших ответов: фильтрация, но они выглядят так же, как мое решение ... и после попытки их, они не t работа.

Вот полное сообщение об ошибке, если я что-то упустил ...

Traceback (most recent call last):
  File "database/database.py", line 272, in <module>
    query_status = add_plain_query_to_database(Query(lang, city))
  File "database/database.py", line 134, in add_plain_query_to_database
    session.commit()  # should add all the pages and posts to the database
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/session.py", line 1036, in commit
    self.transaction.commit()
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/session.py", line 503, in commit
    self._prepare_impl()
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/session.py", line 482, in _prepare_impl
    self.session.flush()
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/session.py", line 2479, in flush
    self._flush(objects)
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/session.py", line 2617, in _flush
    transaction.rollback(_capture_exception=True)
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/util/langhelpers.py", line 68, in __exit__
    compat.reraise(exc_type, exc_value, exc_tb)
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/session.py", line 2577, in _flush
    flush_context.execute()
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/unitofwork.py", line 422, in execute
    rec.execute(self)
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/unitofwork.py", line 589, in execute
    uow,
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/persistence.py", line 245, in save_obj
    insert,
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/persistence.py", line 1137, in _emit_insert_statements
    statement, params
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/engine/base.py", line 982, in execute
    return meth(self, multiparams, params)
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/sql/elements.py", line 293, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/engine/base.py", line 1101, in _execute_clauseelement
    distilled_params,
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/engine/base.py", line 1250, in _execute_context
    e, statement, parameters, cursor, context
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/engine/base.py", line 1476, in _handle_dbapi_exception
    util.raise_from_cause(sqlalchemy_exception, exc_info)
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/util/compat.py", line 398, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb, cause=cause)
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/engine/base.py", line 1246, in _execute_context
    cursor, statement, parameters, context
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/engine/default.py", line 588, in do_execute
    cursor.execute(statement, parameters)
  File "/usr/local/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 205, in execute
    self.errorhandler(self, exc, value)
  File "/usr/local/lib/python2.7/dist-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
    raise errorclass, errorvalue
sqlalchemy.exc.OperationalError: (_mysql_exceptions.OperationalError) (1366, "Incorrect string value: '\\xD8\\xB9\\xD8\\xB1\\xD8\\xA8...' for column 'soup' at row 1")
[SQL: INSERT INTO page (parent_id, url, soup, what, `where`, num_of_posts) VALUES (%s, %s, %s, %s, %s, %s)]
[parameters: (3L, 'https://www.indeed.ca/jobs?q=vue&l=Vancouver%2C+BC&start=20&limit=20', u'<!DOCTYPE html>\n<html dir="ltr" lang="en">\n <head>\n  <meta content="text/html;charset=ignore" http-equiv="content-type"/>\n  <script src="/s/812e ... (649747 characters truncated) ... img = new Image(); img.src = href;}}; window[\'sendPageLoadEndPing\']("serp", "1e2p9l9jm5196800", "1583544444534");\n  </script>\n </body>\n</html>\n', 'vue', 'Vancouver', None)]
(Background on this error at: http://sqlalche.me/e/e3q8)

1 Ответ

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

Вы надеялись получить 'عرب'?

Но какой-то слой менял каждого персонажа Араби c на что-то вроде \\xD8\\xB9. Это 4 шестнадцатеричные цифры D8B9, что составляет один символ UTF-8 для буквы арабского языка c 'AIN'.

арабский язык c символов представляют собой 2-байтовые кодировки в UTF -8. Таким образом, utf8mb4 здесь не требуется. Я хочу сказать, что utf8mb4 против utf8 не является проблемой.

Я подозреваю, что проблема заключается в удвоении обратной косой черты. Текст приходит из кода клиента? Через какое заявление? Можете ли вы сбросить строку в шестнадцатеричном формате из кода клиента?

Проверьте Python подсказки здесь: http://mysql.rjweb.org/doc.php/charcoll#python

Может быть, что-то в этих заметках sqlalchemy:

db_url = sqlalchemy.engine.url.URL(drivername='mysql', host=foo.db_host,
    database=db_schema,
    query={ 'read_default_file' : foo.db_config, 'charset': 'utf8mb4' })

engine = create_engine ('mysql: // root:@localhost/testdb?charset=utf8', encoding = 'utf-8')

Или здесь: https://docs.sqlalchemy.org/en/13/dialects/mysql.html#mysql -unicode

Вы, вероятно, должны удалить len(char.encode...

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