sql >> Base de Datos >  >> RDS >> Mysql

Problema de intercalación mysql-python:¿cómo forzar el tipo de datos Unicode?

Resulta que el problema es bastante incómodo. En resumen, la mayoría de las variedades y especies en tipos de datos de cadena MySQL asigne a un solo tipo de datos en la interfaz de MySQL con un indicador BINARIO adicional.

Por lo tanto, VARCHAR de MySQL , VARBINARY , y un mapa literal de cadena al mismo MySQLdb.constants.FIELD_TYPE.VAR_STRING escriba definiciones de tipo de columna, pero con un MySQLdb.constants.FLAG.BINARY adicional marcar cuando el tipo es VARBINARY o una cadena cotejada con un *_bin colación.

Aunque hay un MySQLdb.constants.FIELD_TYPE.VARCHAR tipo, no pude averiguar cuándo se usa. Como dije, MySQL VARCHAR las columnas se asignan a FIELD_TYPE.VAR_STRING .

La solución se vuelve bastante frágil si su aplicación usa cadenas binarias verdaderas (por ejemplo, almacena imágenes y las obtiene con la misma conexión que el texto), ya que asume la decodificación de todas las cadenas binarias a unicode. Sin embargo, funciona.

Como documentos oficiales estados:

En la práctica, el verdadero dolor en el culo podría ser el proceso de construir su propio diccionario de convertidores. Pero puede importar el predeterminado desde MySQLdb.converters.conversions y parchearlo, o incluso parchearlo en una instancia de Connection. El truco consiste en eliminar un convertidor especial para FLAG.BINARY marcar y agregar un decodificador para todos los casos. Si especifica explícitamente un charset parámetro para MySQLdb.connect , fuerza use_unicode=1 parámetro, que agrega el decodificador por ti, pero puedes hacerlo tú mismo:

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

Probablemente necesites hacer el mismo truco para FIELD_TYPE.STRING si es necesario.

Otra solución es pasar use_unicode=0 explícito a MySQLdb.connect y hacer todas las decodificaciones en su código, pero no lo haría.

Espero que esto pueda ser útil para alguien.