Почему Flask Migrations не обнаруживает изменение длины поля? - PullRequest
1 голос
/ 24 октября 2019

У меня есть следующая модель, я хочу изменить длину имени, когда я выполняю миграцию, она не обнаруживает изменения

class Client(db.Model):
    __tablename__ = "client"
    client_id = db.Column(
        db.Integer,
        primary_key=True,
        autoincrement=True
    )
    name = db.Column(db.String(65))
    email = db.Column(db.String(255)) 

Например, изменить на

name = db.Column(db.String(100))

NFO [alembic.env] No changes in schema detected.

Но когда я меняю имя, если оно обнаруживает изменения

INFO  [alembic.autogenerate.compare] Detected added column 'client.name_test'
INFO  [alembic.autogenerate.compare] Detected removed column 'client.name'

1 Ответ

4 голосов
/ 24 октября 2019

TL; DR :

context.configure(
    # ...
    compare_type = True
)

Я проверял это на изменении длины строки в бэкэнде PG, и это работает, однако, как вы можете видеть ниже, документы в настоящее времязаявить, что это не должно. Вот соответствующий раздел документов :

Автогенерация может опционально определять :

  • Изменение типа столбца. Это произойдет, если для параметра EnvironmentContext.configure.compare_type задать значение True или пользовательскую вызываемую функцию. Реализация по умолчанию обнаруживает только основные изменения типа, например, между Numeric и String, а не обнаруживает изменения в аргументах, таких как длина , точность или члены перечисления. Логика сравнения типов расширяема, чтобы обойти эти ограничения, подробности см. В разделе Сравнение типов.

И Справочник по API для compare_type состояний:

Указывает поведение сравнения типов во время операции автогенерации. По умолчанию используется значение False, которое отключает сравнение типов. Установите значение True, чтобы включить сравнение типов по умолчанию, точность которого варьируется в зависимости от серверной части. См. Сравнение типов для примера, а также информацию о других параметрах сравнения типов.

Наконец, в разделе под названием Сравнение типов приведен следующий пример, как включитьсравнение типов:

context.configure(
    # ...
    compare_type = True
)

Вы найдете вызов context.configure() в скрипте env.py, который автоматически генерируется алембом, вложенным в контекст соединения:

with connectable.connect() as connection:
    context.configure(
        connection=connection, target_metadata=target_metadata
    )

. .. и просто добавьте туда параметр compare_type.

В том же разделе они говорят:

Примечание Логика сравнения типов по умолчанию (которая является конечнойрасширяемый пользователем) в настоящее время работает только для основных изменений типа, например, между Numeric и String. Логика не обнаружит такие изменения, как:

  • изменения между типами, имеющими одинаковую «привязку типов», например, между VARCHAR и TEXT или FLOAT и NUMERIC

  • изменения между аргументами в типе, , такие как длина строк , точные значения для чисел, элементы внутри перечисления.

Обнаружение таких параметров является долгосрочным проектом на стороне SQLAlchemy.

Так что интересно видеть, что в документах пару раз упоминалось, что это не должно работать. Как упоминалось ранее, я проверил это на postgres и могу подтвердить, что установка compare_type=True генерирует ревизию для длины столбца, поэтому, возможно, документы немного отстают от этого, или сопровождающие не готовы объявитьэто еще не все возможности.

Я также тестировал MySQL и могу подтвердить, что изменения длины строки также регистрируются, если compare_type=True.

...