Mysql
 sql >> база данни >  >> RDS >> Mysql

Как да накарам SQLAlchemy да вмъкне правилно уникод многоточие в mySQL таблица?

Съобщението за грешка

UnicodeEncodeError: 'latin-1' codec can't encode character u'\u2026' 
in position 35: ordinal not in range(256)

изглежда показва, че някакъв езиков код на Python се опитва да преобразува знака \u2026 в низ Latin-1 (ISO8859-1) и той е неуспешен. Не е изненадващо, че този знак е U+2026 ХОРИЗОНТАЛНА ЕЛИПСА , който няма нито един еквивалентен знак в ISO8859-1.

Отстранихте проблема, като добавихте заявката ?charset=utf8 във вашето обаждане за връзка с SQLAlchemy:

import sqlalchemy
from sqlalchemy import create_engine, MetaData, Table

db = create_engine('mysql://user:[email protected]/db?charset=utf8')

Разделът URL адреси на база данни от документацията на SQLAlchemy ни казва, че URL, започващ с mysql обозначава MySQL диалект, използвайки mysql-python шофьор.

Следният раздел, Персонализиран DBAPI аргументи connect() , ни казва, че аргументите на заявката се предават към основния DBAPI.

И така, какво означава mysql-python драйвер на параметър {charset:'utf8'} ? Раздел Функции и атрибути от тяхната документация се казва за charset атрибут "...Ако е налице, наборът от символи за връзка ще бъде променен на този набор от знаци, ако не са равни."

За да разберем какво означава наборът от символи за връзка, се обръщаме към 10.1.4. Набори от символи за свързване и съпоставяне от справочното ръководство за MySQL 5.6. За да бъде накратко, MySQL може да интерпретира входящите заявки като кодиране, различно от набора от знаци на базата данни и различно от кодирането на върнатите резултати от заявката.

Тъй като съобщението за грешка, което съобщихте, изглежда като съобщение за грешка на Python, а не на SQL, ще предполагам, че нещо в SQLAlchemy или mysql-python се опитва да преобразува заявката в кодиране на връзката по подразбиране на latin-1 преди да го изпратите. Това е, което предизвиква грешката. Въпреки това, низът на заявката ?charset=utf8 във вашия connect() повикването променя кодирането на връзката и U+2026 ХОРИЗОНТАЛНА ЕЛИПСА е в състояние да премине.

Актуализация: вие също така питате, "ако премахна опцията за набор от знаци и след това кодирам описанието с помощта на .encode('cp1252'), ще мине добре. Как многоточе може да премине през cp1252, но не и unicode?"

кодирането cp1252 има знак с хоризонтална многоточия в байтова стойност \x85 . По този начин е възможно да се кодира Unicode низ, съдържащ U+2026 ХОРИЗОНТАЛНА ЕЛИПСА в cp1252 без грешка.

Не забравяйте също, че в Python низовете на Unicode и байтовите низове са два различни типа данни. Разумно е да се спекулира, че MySQLdb може да има политика за изпращане само на байтови низове през SQL връзка. По този начин той ще кодира заявка, получена като Unicode низ, в байтов низ, но ще остави заявка, получена като низ от байтове, сама. (Това е спекулация, не съм гледал изходния код.)

В проследяването, което публикувахте, последните два реда (най-близо до мястото на възникване на грешката) показват имената на методите literal , последвано от unicode_literal . Това има тенденция да подкрепя теорията, че MySQLdb кодира заявката, която получава като Unicode низ, в низ от байтове.

Когато сами кодирате низа на заявката, вие заобикаляте частта от MySQLdb, която прави това кодиране по различен начин. Имайте предвид обаче, че ако кодирате низа на заявката по различен начин от извикания набор от знаци за MySQL връзката, тогава ще имате несъответствие в кодирането и текстът ви вероятно ще бъде съхранен погрешно.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да конвертирам всички таблици в базата данни в едно съпоставяне?

  2. изтрийте ред в моята база данни с помощта на php pdo

  3. Архивиране на база данни на mysql с mysqldump

  4. Повторно въведена Неизвестна грешка в индекса на първоначалния набор от символи?

  5. WordPress изготвено изявление с условие IN().