Независимый от базы данных способ сказать, что я хочу, чтобы столбец был UTF-8 в SQLAlchemy?

#python #mysql #sqlite #utf-8 #sqlalchemy

#python #mysql #sqlite #utf-8 #sqlalchemy

Вопрос:

Я заметил, что моя база данных MySQL не настроена на использование UTF-8 по умолчанию. latin1_swedish_ci Вместо этого выбирается сопоставление.

Поэтому, естественно, я столкнулся с сообщением пользователя об ошибке, что мое приложение не поддерживает специальные символы. Я пошел и убедился, что мое приложение правильно обрабатывает UTF-8, написал тест, и, конечно же, он отлично работал с SQLite в памяти, но не с производственным MySQL.Решение, которое я, кажется, получаю из документации по SQLAlchemy, состоит в том, чтобы передать сопоставление в моем столбце:

  column = db.Column(db.String(500, collation='utf8_general_ci'))
 

К сожалению, это приводит к сбою моих модульных тестов, основанных на SQLite — utf8_general_ci не поддерживается кодировкой для SQLite. Это специфично для MySQL.

SQLite, похоже, подходит для UTF-8 без указания сортировки. Я могу и выполняю тестирование с помощью MySQL, но база данных SQLite в памяти — это гораздо более быстрый и простой вариант тестирования для точечных тестов. Я действительно ставлю во главу угла простоту тестирования, поэтому возвращение к тестированию с помощью SQLite является для меня большим приоритетом.

Другие вещи, которые я пробовал

Я также пытался добавить

 charset=utf8amp;use_unicode=1
 

к моей строке подключения. Я также использовал db.Unicode вместо db.String . Казалось, это не имело никакого значения.

Вопрос

Есть ли прямой и независимый от базы данных способ через SQLAlchemy указать, что столбец должен быть закодирован с помощью UTF-8?

Комментарии:

1. Любопытно! Почему бы вам не изменить параметры сортировки в БД и самих таблицах?

2. Если я собираюсь это сделать, я хочу сделать это через SQLAlchemy или через миграцию. Я бы предпочел не делать ничего, кроме «db.create_all()»…

Ответ №1:

Что решило мою проблему, так это изменить параметры сортировки в таблице с помощью __table_args__ :

 class Foo(Base):
    __tablename__ = "foo"
    __table_args__ = {'mysql_collate': 'utf8_general_ci'}

    ...

    column = db.Column(db.String(500))
 

SQLite счастливо игнорирует этот параметр mysql. MySQL подбирает его соответствующим образом.