Comment décaper des unicodes et les enregistrer dans des bases de données utf-8
J'ai une base de données (mysql) où je veux stocker marinés données.
Les données peuvent être, par exemple, un dictionnaire, qui peut contenir de l'unicode, par exemple
data = {1 : u'é'}
et la base de données (mysql) est en utf-8.
Quand je cornichon,
import pickle
pickled_data = pickle.dumps(data)
print type(pickled_data) # returns <type 'str'>
l'résultant pickled_data est une chaîne de caractères.
Quand j'essaie de les stocker dans une base de données (par exemple, dans un Champ de texte), cela peut causes des problèmes. En particulier, je suis arriver à un certain moment,
UnicodeDecodeError "'utf8' codec can't decode byte 0xe9 in position X"
lorsque vous essayez d'enregistrer le pickled_data dans la base de données. Cela a un sens parce que pickled_data peut avoir des non-caractères utf-8. Ma question est de savoir comment dois-je stocker pickled_data sur utf-8 base de données?
Je vois deux candidats possibles:
- Encoder le résultat de la saumure.vidage de l'utf-8 et de le stocker. Quand j'ai envie de cornichon.charge, j'ai pour le décoder.
- Magasin de la marinés chaîne de caractères dans un format binaire (comment?), qui des forces de tous les caractères à l'intérieur de l'ascii.
Mon problème est que je ne vois pas quelles sont les conséquences du choix de l'une de ces options dans le long terme. Depuis le changement déjà nécessite un certain effort, je suis poussé à demander un avis sur cette question, en demandant pour un éventuel meilleurs candidats.
(P. S. C'est par exemple utile dans Django)
source d'informationauteur Jorge Leitão
Vous devez vous connecter pour publier un commentaire.
Pickle données est opaque, les données binaires, même lorsque vous utilisez le protocole de la version 0:
Lorsque vous essayez de stocker dans une
TextField
Django va essayer de le décoder des données en UTF8 pour stocker; c'est ce qui échoue parce que ce n'est pas codé en UTF-8 données: il s'agit des données binaires au lieu:La solution est de pas essayer de les stocker dans un
TextField
. Utiliser unBinaryField
à la place:Vous avez un
bytes
valeur (Python 2 chaînes sont des chaînes d'octets, renommé pourbytes
en Python 3).Si vous insistez pour stocker les données dans un champ de texte, explicitement décoder comme
latin1
; le Latin 1 codec cartes octets un par un en Unicode codepoints:et assurez-vous que vous encoder de nouveau avant de unpickling de nouveau:
Notez que si vous laissez cette valeur à aller dans le navigateur et de retour à nouveau dans un champ de texte, le navigateur est susceptible d'avoir remplacé les caractères dans les données. Internet Explorer va remplacer
\n
caractères avec\r\n
par exemple, parce qu'il suppose qu'il est, le traitement de texte.Pas que vous ne doit jamais permettre d'accepter les achards de données à partir d'une connexion réseau en tout cas, parce que c'est un trou de sécurité en attente pour l'exploitation.