Как вернуть str из MySQL, используя mysql.connector?

Я пытаюсь использовать MySQL Connector/Python из mysql.com с Python 3.

У меня есть таблицы в кодировке UTF-8, и когда я выбираю строки, все мои столбцы chars возвращаются как bytearray. Это делает некоторую путаницу.

Как я могу получить непосредственно str?

UPD:

# -*- coding: utf-8 -*-
import mysql.connector
con = mysql.connector.connect( user ="root", db = "vg_site_db", charset = 'utf8' )
cursor = con.cursor()
sql = """select caption from domains
"""
cursor.execute( sql )
row = cursor.fetchone()
while row is not None:
    print( row )
    row = cursor.fetchone()

выход:

(bytearray(b'ezsp.ru'),)
(bytearray(b'eazyshop.ru'),)
(bytearray(b'127.0.0.1:8080'),)
(bytearray(b'rmsvet.ru'),)

Я хочу:

('ezsp.ru',)
('eazyshop.ru',)
('127.0.0.1:8080',)
('rmsvet.ru',)

UPD2:

Мои таблицы используют COLLATE utf8_bin.

Ответ 1

Похоже, это происходит, когда вы используете двоичную сортировку, по крайней мере, то же самое случилось со мной. Чтобы преобразовать байтовые массивы в строки Unicode, вы можете добавить собственный класс конвертера:

class MyConverter(mysql.connector.conversion.MySQLConverter):

    def row_to_python(self, row, fields):
        row = super(MyConverter, self).row_to_python(row, fields)

        def to_unicode(col):
            if isinstance(col, bytearray):
                return col.decode('utf-8')
            return col

        return[to_unicode(col) for col in row]

sql = mysql.connector.connect(converter_class=MyConverter, host=...)

Ответ 2

MySQL Connector возвращает строки (как хранится с использованием CHAR, VARCHAR и TEXT типов данных) в качестве bytearray, когда соответствующие столбцы определяются с бинарной сортировкой (например, utf8_bin). Вы должны вызвать .decode() для значений, чтобы получить строки Python, например:

for row in cursor:
    caption = row[0].decode()

Тем не менее, если у вас нет особых требований использовать utf8_bin, гораздо лучше использовать utf8mb4 символов utf8mb4 с сопоставлением utf8mb4_unicode_ci на уровне базы данных. Это решило бы вашу проблему и обеспечило бы полную поддержку Unicode. Смотрите это и это более подробно.

Ответ 3

Добавление mysql-connector-python==8.0.17 в файл require.txt решило эту проблему для меня.

Ответ 5

Я не думаю, что вы можете заставить курсор возвращать строки. MySQL Connector Documentation говорит, что они решили вернуть bytearrays, так что им нужно поддерживать только одну базу кода для Python2 и Python3:

С использованием "сырых" курсоров возвращаемые значения имеют тип bytearray. Это необходимо для того, чтобы оба Python 2 и 3 возвращали одни и те же данные.

Я рассмотрел эту проблему, используя понимание списка для декодирования каждого байта в строке:

for row in cursor:
    type_fixed_row = tuple([el.decode('utf-8') if type(el) is bytearray else el for el in row])
    print( type_fixed_row )

Ответ 6

Легкий способ решить эту проблему - убедиться, что вы извлекаете "строки" из своей таблицы MySQL. Для этого вам просто нужно добавить CAST в свой запрос следующим образом:

 # -*- coding: utf-8 -*-
import mysql.connector
con = mysql.connector.connect( user ="root", db = "vg_site_db", charset = 'utf8' )
cursor = con.cursor()
sql = "select CAST(caption as CHAR(50)) from domains"
cursor.execute( sql )
row = cursor.fetchone()
while row is not None:
    print( row )
    row = cursor.fetchone()

Это должно сработать для вас.