7
votes

Python - Problème stockant le caractère Unicode à MySQL avec Django

J'ai la chaîne xxx pré>

qui doit être indiquée comme p> xxx pré>

mais c'est un autre problème. Mon problème à portée de main est que je le mettez dans un modèle puis en essayant de le sauvegarder dans une base de données. AKA: P>

DEFAULT_CHARSET = 'utf-8'


5 commentaires

On dirait que ça n'aime pas le personnage unique (') ...


comment? C'est Borking sur le \ U2122, je pense ...


Pouvez-vous fournir le reste de la trace de la pile? Il est possible que le code de base de données réel gère correctement votre chaîne unicode, mais un code de journalisation quelque part est en train de gâcher.


Et essayez de minimiser le problème: modèles.achievement.ObjectS.Create (nom = u "\ u2122") modèles.achievement.ObjectS.create (nom = u "Lecture de miroir's Edge")


Quelle collation de base de données utilisez-vous?


7 Réponses :


1
votes

Je travaillais à cet hier, et j'ai trouvé que l'ajout de "charset = utf8" et "user_unicode = 1" à la chaîne de connexion a fait fonctionner le fonctionnement (en utilisant SQLalchemy, devinez que c'est le même problème).

Donc, ma corde ressemble à: "MySQL: // Utilisateur: Pass @ Host: 3306 / Base de données? Utilisez_unicode = 1 & Charset = UTF8"


1 commentaires

Engage furtif dans les fichiers Django, in ./db/backends/mysql/base.py Il a kwargs = {'conv': django_conversions, 'charset': 'utf8', 'user_unicode': true,} Je pense donc que c'est déjà connecté comme ça.



3
votes

Vous utilisez des chaînes de type 'Unicode'. Si votre modèle ou votre backend SQL ne les supporte pas ou ne sait pas comment convertir en UTF-8, faites simplement la conversion vous-même. Stick avec des chaînes simples (python STR) et convertir comme dans

a = models.Achievement(name=u"Played Mirror's Edge\u2122".encode("UTF-8"))


2 commentaires

Pourquoi le bowvote sur cette réponse? Nikolai semble être sur la bonne voie pour moi à noter que Unicode est pas la même chose que UTF-8 ...


Si je fais quelque chose comme ça, alors quand j'essaie d'imprimer le modèle après l'insert, je reçois DjangounicodeDedeCodeError de forcer_unicode. Si je l'extrait de la base de données, il est parfait, mais imprime l'objet inséré à l'origine jette le DjangounicodeDedeError. :(



-1
votes

Pour moi, l'Apostrophe a l'air étrange, si cela ne devrait pas être échappé comme: xxx


2 commentaires

La chaîne donnée et la vôtre sont équivalentes. Tapez-le dans un interprète python. >>> U "Lecture de miroir \ 's Edge \ u21222" U "Edge de miroir" >>> U "Lecture de miroir's Edge \ u2122" U "a joué le bord de miroir \ u2122"


L'apostrophe ne doit pas être échappé. Échapper un caractère qui ne doit pas être échappé, il suffit d'obscorer les codes. Mais vous avez raison que les bowvotes devraient être commentés.



0
votes

Je suis d'accord avec Nikolai. J'ai déjà rencontré problème à utiliser UTF-8, même en python pur (2.5).

J'ai finalement utilisé la fonction Unicode (?): xxx

codage dépend de Les paramètres régionaux, si je me souviens bien: xxx

ajoutez peut-être le Python Unicode Howto ?


0 commentaires

4
votes

Quelques remarques:

  • Python 2.x a deux types de chaîne

    • "str", qui est fondamentalement un tableau d'octets (afin que vous puissiez stocker tout ce que vous aimez, il)
    • "unicode", qui est encodé UCS2 / UCS4 Unicode interne
    • Les instances de ces types sont considérées comme des données "décodées". La représentation interne est la référence, de sorte que vous "décodez" des données externes et "encoder" dans un format externe.

    • Une bonne stratégie consiste à décoder le plus tôt possible lorsque les données entrent dans le système et l'encode le plus tard possible. Essayez d'utiliser Unicode pour les cordes dans votre système autant que possible. (Je ne suis pas d'accord avec Nikolai à cet égard).

    • Cet aspect codant s'applique à la réponse de Nicolai. Il prend la chaîne d'origine Unicode et le code dans UTF-8. Mais ce ne résout pas le problème (au moins pas généralement), car le tampon d'octets résultant peut toujours contenir des octets en dehors de la plage (127) (je n'ai pas vérifié pour \ u2122), ce qui signifie que vous toucherez à nouveau la même exception.

    • L'analyse de Nicolai détient que vous passez une chaîne unicode, mais quelque part dans le système, il est considéré comme une instance STR. Il suffit de si une fonction STR () est appliquée à votre argument Unicode.

    • Dans ce cas, Python utilise le codage par défaut ainsi que l'ASCII si vous ne le modifiez pas. Il existe une fonction SyS.SeDeFaulleCoding que vous pouvez utiliser pour passer à E.G. UTF-8, mais la fonction n'est disponible que dans un contexte limitée, vous ne pouvez donc pas l'utiliser facilement dans le code de l'application.

    • Mon sentiment est que le problème est quelque part plus profondément dans les couches que vous appelez. Malheureusement, je ne peux pas commenter sur Django ou MySQL / SQLalchemy, mais je me demande si vous pouviez spécifier un type Unicode lors de la déclaration de l'attribut "Nom" de votre modèle. Ce serait une bonne pratique DB de gérer les informations de type sur le terrain. Peut-être qu'il y a une alternative à Charfield ?!

    • et oui, vous pouvez intégrer en toute sécurité un seul devis (') dans une chaîne cotée double ("), et vice versa.


1 commentaires

Merci, bonne information. En effet, l'UTF8 a également le même problème avec ASCII: UNICODE.ENCODE (U "Lecture de Mirror's Edge \ U2122", "UTF8") "Edge de miroir joué \ xe2 \ x84 \ xa2" . J'essaie d'utiliser Unicode tout le chemin (que je faisais si je faisais) et ma base de données est codée dans UTF8.



0
votes

J'avais des problèmes similaires avec MySQL et Postgres, mais pas de problèmes avec SQLLITE.

C'est comme ça que j'ai résolu le problème avec Postgres (n'a pas testé ce truc avec MySQL mais ID Asmez cela le résoudrait également) P >

dans le fichier où vous traitez avec la chaîne Unicode do un p> xxx pré>

et assumez UNRSIS est la variable contenant la chaîne, faites un P>

keyword = SafeUnicode(ht.a.string)


1 commentaires

Du Docs pour SafeUnicode "" "une sous-classe Unicode spécialement marquée comme" sûre "à des fins de sortie HTML." "" Je pense que vous ne le convertissez pas en unicode avec la fonction. J'utilise effectivement de nombreuses façons d'obtenir les données, certaines expressions régulières sur Urllib2.Open (). Lisez () une belle soupe. Je pensais qu'une belle soupe utilisée Unicode par défaut ...



12
votes

Merci à tous ceux qui postais ici. Cela aide vraiment ma connaissance unicode (et d'autres personnes hospitalisées a appris quelque chose).

Nous semblions être tous aboyer le mauvais arbre depuis que j'ai essayé de simplifier mon problème et de ne pas donner toutes les informations. Il semble que je n'utilisais pas "de vraies" chaînes unicode, mais plutôt belle-gens.NavigAgLayString qui se reproduisent comme des chaînes unicode. Donc, toutes les impressions ressemblaient à unicode, mais elles n'étaient pas. P>

Quelque part dans la bibliothèque mysqldb, ils ne pouvaient pas gérer ces cordes. p>

Ceci a fonctionné: p> xxx pré>

d'autre part: p> xxx pré>

mais cela fonctionne:

>>> Achievement.objects.get(name = unicode(b))
<Achievement: Mirror's Edgeâ„¢>


3 commentaires

Merci, j'ai trouvé cela via Google et a appris beaucoup des réponses. Ensuite, j'ai lu à la fin que vous utilisiez une belle soupe. Comme moi. :)


Même après avoir forcé Unicode sur toutes les valeurs qui reviennent magnifiques, je ne suis pas en mesure de le faire fonctionner. Je reçois une erreur lors de l'impression sur le terminal et de l'insérer dans MySQL. L'erreur est du formulaire "" Latin-1 'codec ne peut pas encoder le caractère u' \ u03bc 'en position 545: ordinal non dans la plage (256)'


BTW, la même chose arrive avec lxml . Si vous passez dans le texte de lxml directement sur mysqldb, (qui a le type ), alors vous obtenez le même message d'erreur .