Как вернуть 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 решило эту проблему для меня.
Ответ 4
На основе вашего SQL-запроса:
select caption from domains
Вы можете прочитать столбец caption
непосредственно из извлеченного row
Пример 1:
print row.caption
Пример 2:
print row[ 0 ]
Ссылка на документацию:
Ответ 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()
Это должно сработать для вас.