Het blijkt dat het probleem nogal onhandig is. Kortom, de meeste variaties en soorten in MySQL string datatypes toewijzen aan een enkel datatype in de interface van MySQL met een extra BINARY-vlag.
Dus MySQL's VARCHAR
, VARBINARY
, en een letterlijke tekenreeks naar dezelfde MySQLdb.constants.FIELD_TYPE.VAR_STRING
typ kolomtypedefinities in, maar met een extra MySQLdb.constants.FLAG.BINARY
vlag als het type VARBINARY
is of een string verzameld met een *_bin
sortering.
Ook al is er een MySQLdb.constants.FIELD_TYPE.VARCHAR
type, ik heb niet kunnen achterhalen wanneer het wordt gebruikt. Zoals ik al zei, MySQL VARCHAR
kolommen worden toegewezen aan FIELD_TYPE.VAR_STRING
.
De oplossing wordt nogal kwetsbaar als uw toepassing echte binaire tekenreeksen gebruikt (u slaat bijvoorbeeld afbeeldingen op en haalt ze op met dezelfde verbinding als tekst), omdat het ervan uitgaat dat alle binaire reeksen worden gedecodeerd naar unicode. Hoewel, het werkt.
Als officiële docs staten:
In de praktijk kan de echte pijn in de kont het proces zijn van het construeren van uw eigen convertorswoordenboek. Maar u kunt de standaard importeren vanuit MySQLdb.converters.conversions
en patch het, of patch het zelfs op een instantie van de Connection. De truc is om een speciale converter te verwijderen voor een FLAG.BINARY
flag en voeg een decoder toe voor alle gevallen. Als u expliciet een charset
opgeeft parameter voor MySQLdb.connect
, het dwingt use_unicode=1
parameter, die de decoder voor u toevoegt, maar u kunt het zelf doen:
>>> 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',)
Mogelijk moet u dezelfde hack uitvoeren voor FIELD_TYPE.STRING
indien nodig.
Een andere oplossing is het expliciet doorgeven van use_unicode=0
naar MySQLdb.connect
en maak alle decoderingen in je code, maar ik zou het niet doen.
Hoop, dit kan nuttig zijn voor iemand.