sql >> Databasteknik >  >> RDS >> Mysql

mysql-python-kollationsproblem:hur tvingar man fram Unicode-datatyp?

Det visar sig att problemet är ganska besvärligt. Kort sagt, de flesta varianter och arter i MySQL-strängdatatyper a> map till en enskild datatyp i MySQL:s gränssnitt med en extra BINÄR flagga.

Alltså MySQL:s VARCHAR , VARBINARY , och en bokstavlig strängkarta till samma MySQLdb.constants.FIELD_TYPE.VAR_STRING skriv in kolumntypsdefinitioner, men med ytterligare en MySQLdb.constants.FLAG.BINARY flagga när typen är VARBINARY eller en sträng sorterad med en *_bin sammanställning.

Även om det finns en MySQLdb.constants.FIELD_TYPE.VARCHAR typ, jag kunde inte ta reda på när den används. Som jag sa, MySQL VARCHAR kolumner mappas till FIELD_TYPE.VAR_STRING .

Lösningen blir ganska ömtålig om din applikation använder sanna binära strängar (till exempel lagrar du bilder och hämtar dem med samma anslutning som text), eftersom den förutsätter avkodning av alla binära strängar till unicode. Fast det fungerar.

Som officiella dokument står:

I praktiken kan verklig smärta i röven vara processen att skapa din egen omvandlarordbok. Men du kan importera standarden från MySQLdb.converters.conversions och patcha det, eller till och med patcha det på en instans av Connection. Tricket är att ta bort en speciell omvandlare för en FLAG.BINARY flagga och lägg till en avkodare för alla fall. Om du uttryckligen anger en charset parameter för MySQLdb.connect , tvingar den use_unicode=1 parameter, som lägger till avkodaren åt dig, men du kan göra det själv:

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

Du kan förmodligen behöva göra samma hack för FIELD_TYPE.STRING om det behövs.

En annan lösning är att skicka explicit use_unicode=0 till MySQLdb.connect och gör alla avkodningar i din kod, men jag skulle inte göra det.

Hoppas det här kan vara användbart för någon.



  1. Lata hämta en kolumn (klassattribut) med Hibernate

  2. Skillnad mellan Oracle jdbc-drivrutinsklasser?

  3. Hur parallella planer startar – del 1

  4. använder where och inner join i mysql