Mysql
 sql >> Database >  >> RDS >> Mysql

problema di confronto mysql-python:come forzare il tipo di dati unicode?

Si scopre che il problema è piuttosto imbarazzante. In breve, la maggior parte delle varietà e delle specie in tipi di dati di stringhe MySQL mappa a un singolo tipo di dati nell'interfaccia di MySQL con un flag BINARY aggiuntivo.

Pertanto, VARCHAR di MySQL , VARBINARY e una mappa letterale stringa allo stesso MySQLdb.constants.FIELD_TYPE.VAR_STRING digitare le definizioni del tipo di colonna, ma con un ulteriore MySQLdb.constants.FLAG.BINARY flag quando il tipo è VARBINARY o una stringa confrontata con un *_bin confronto.

Anche se esiste un MySQLdb.constants.FIELD_TYPE.VARCHAR tipo, non sono riuscito a scoprire quando viene utilizzato. Come ho detto, MySQL VARCHAR colonne mappa a FIELD_TYPE.VAR_STRING .

La soluzione diventa piuttosto fragile, se la tua applicazione utilizza stringhe binarie vere (ad esempio, memorizzi immagini e le recuperi con la stessa connessione del testo), poiché presuppone la decodifica di tutte le stringhe binarie in unicode. Comunque funziona.

Come documenti ufficiali afferma:

In pratica, il vero dolore nel culo potrebbe essere il processo di costruzione del tuo dizionario di convertitori. Ma puoi importare quello predefinito da MySQLdb.converters.conversions e patchalo, o addirittura patchalo su un'istanza di Connection. Il trucco è rimuovere un convertitore speciale per un FLAG.BINARY flag e aggiungi un decoder per tutti i casi. Se specifichi esplicitamente un charset parametro per MySQLdb.connect , forza use_unicode=1 parametro, che aggiunge il decoder per te, ma puoi farlo da solo:

>>> 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',)

Probabilmente potresti dover fare lo stesso hack per FIELD_TYPE.STRING se richiesto.

Un'altra soluzione è passare use_unicode=0 esplicito a MySQLdb.connect e fare tutte le decodifiche nel tuo codice, ma non lo farei.

Spero che questo possa essere utile a qualcuno.