Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Problema de agrupamento mysql-python:como forçar o tipo de dados unicode?


Acontece que o problema é bastante estranho. Em resumo, a maioria das variedades e espécies em tipos de dados de string MySQL mapear para um único tipo de dados na interface do MySQL com um sinalizador BINARY adicional.

Assim, o VARCHAR do MySQL , VARBINARY , e um mapa literal de string para o mesmo MySQLdb.constants.FIELD_TYPE.VAR_STRING digite nas definições de tipo de coluna, mas com um MySQLdb.constants.FLAG.BINARY adicional sinalizar quando o tipo for VARBINARY ou uma string agrupada com um *_bin agrupamento.

Mesmo que haja um MySQLdb.constants.FIELD_TYPE.VARCHAR type, não consegui descobrir quando é usado. Como eu disse, MySQL VARCHAR colunas mapeadas para FIELD_TYPE.VAR_STRING .

A solução se torna bastante frágil, se seu aplicativo usa strings binárias verdadeiras (por exemplo, você armazena imagens e as busca com a mesma conexão que o texto), pois assume a decodificação de todas as strings binárias para unicode. Embora, ele funciona.

Como documentos oficiais afirma:

Na prática, uma verdadeira dor de cabeça pode ser o processo de construir seu próprio dicionário de conversores. Mas você pode importar o padrão de MySQLdb.converters.conversions e corrigi-lo, ou até mesmo corrigi-lo em uma instância do Connection. O truque é remover um conversor especial para um FLAG.BINARY sinalizar e adicionar um decodificador para todos os casos. Se você especificar explicitamente um charset parâmetro para MySQLdb.connect , força use_unicode=1 parâmetro, que adiciona o decodificador para você, mas você pode fazer isso sozinho:
>>> 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',)

Talvez você precise fazer o mesmo hack para FIELD_TYPE.STRING se necessário.

Outra solução é passar use_unicode=0 explícito para MySQLdb.connect e fazer todas as decodificações no seu código, mas eu não faria.

Espero que isso possa ser útil para alguém.