Mysql
 sql >> Base de données >  >> RDS >> Mysql

Problème de classement mysql-python :comment forcer le type de données unicode ?

Il s'avère que le problème est plutôt gênant. En bref, la plupart des variétés et des espèces dans les types de données de chaîne MySQL mapper à un seul type de données dans l'interface de MySQL avec un indicateur BINARY supplémentaire.

Ainsi, le VARCHAR de MySQL , VARBINARY , et un littéral de chaîne correspond au même MySQLdb.constants.FIELD_TYPE.VAR_STRING type dans les définitions de type de colonne, mais ayant un MySQLdb.constants.FLAG.BINARY supplémentaire indicateur lorsque le type est VARBINARY ou une chaîne assemblée avec un *_bin classement.

Même s'il existe un MySQLdb.constants.FIELD_TYPE.VARCHAR type, je n'ai pas réussi à savoir quand il est utilisé. Comme je l'ai dit, MySQL VARCHAR les colonnes correspondent à FIELD_TYPE.VAR_STRING .

La solution devient plutôt fragile, si votre application utilise de vraies chaînes binaires (par exemple, vous stockez des images et les récupérez avec la même connexion que du texte), car elle suppose de décoder toutes les chaînes binaires en unicode. Cependant, cela fonctionne.

En tant que docs indique :

En pratique, la vraie douleur dans le cul pourrait être le processus de construction de votre propre dictionnaire de convertisseurs. Mais vous pouvez importer celui par défaut depuis MySQLdb.converters.conversions et patchez-le, ou même patchez-le sur une instance de Connection. L'astuce consiste à supprimer un convertisseur spécial pour un FLAG.BINARY flag et ajouter un décodeur pour tous les cas. Si vous spécifiez explicitement un charset paramètre pour MySQLdb.connect , il force use_unicode=1 paramètre, qui ajoute le décodeur pour vous, mais vous pouvez le faire vous-même :

>>> con = MySQLdb.connect(**params)
>>> con.converter[FIELD_TYPE.VAR_STRING]
[(128, <type 'str'>), (None, <function string_decoder at 0x01FFA130>)]
>>> con.converter[FIELD_TYPE.VAR_STRING] = [(None, con.string_decoder)]
>>> c = con.cursor()
>>> c.execute("SELECT %s COLLATE utf8_bin", u'м')
1L
>>> c.fetchone()
(u'\u043c',)

Vous devrez probablement faire le même hack pour FIELD_TYPE.STRING si nécessaire.

Une autre solution consiste à passer explicitement use_unicode=0 à MySQLdb.connect et faire tous les décodages dans votre code, mais je ne le ferais pas.

J'espère que cela pourrait être utile à quelqu'un.