Миграция Flask для нескольких баз данных

#python #flask #flask-sqlalchemy #alembic #flask-migrate

#python #flask #flask-sqlalchemy #перегонный куб #flask-миграция

Вопрос:

Чтобы дать немного информации о нашем приложении, мы уже настроили базу данных для существующих конечных точек в приложении. Теперь появилось новое требование добавлять конечные точки в одно и то же приложение, взаимодействующее с другой базой данных. Как указано в документации flask-sqlalchemy здесь, чтобы заставить Flask-Migrate работать с несколькими базами данных, мы удалили предыдущие миграции, добавили SQLALCHEMY_BINDS в конфигурации, добавили bind_key в моделях и использовали следующую команду;

 flask db init --multidb
  

Это успешно создало совершенно новую папку migrations с папкой versions. Затем мы использовали следующую команду;

 flask db migrate
  

Это создало новый файл миграции с соответствующим кодом миграции (созданный автоматически Alembic) для создания новых таблиц в новой базе данных, а также добавило alembic_version таблицу в новую базу данных. Во вновь созданный файл миграции для старой / существующей базы данных не был добавлен код миграции (как и ожидалось), поскольку в модель, связанную с этой существующей базой данных, не было внесено никаких изменений. Затем мы продолжили делать:

 flask db upgrade
  

и все сработало так, как ожидалось. Таблицы были успешно созданы в новой базе данных, и мы смогли взаимодействовать с таблицами с недавно определенными конечными точками.

Теперь появилось еще одно требование для добавления новых столбцов к этим вновь созданным таблицам во второй базе данных. Итак, мы добавили столбцы в модель, и теперь мы пытаемся migrate снова, но мы продолжаем получать следующую ошибку:

 INFO  [alembic.env] Migrating database <default>
INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
ERROR [root] Error: Target database is not up to date.
  

Что мы пробовали до сих пор,

  1. Удалил папку migrations.
  2. Повторно запустите цикл инициализации-миграции-обновления.
  3. Убедился, что все перегонные версии синхронизированы (перегонная таблица в обеих базах данных, заголовок в репозитории).
  4. Мы также попытались выполнить миграцию одной базы данных, и это сработало. Почему-то кажется, что при переносе нескольких баз данных возникает проблема.

ИСХОДНАЯ КОНФИГУРАЦИЯ (одна база данных):

 # DB path definition
SQLALCHEMY_DATABASE_URI='full_path_to_db'

# Model
class Table1(db.Model):
    #column declarations with datatypes
  

НОВАЯ КОНФИГУРАЦИЯ (с несколькими базами данных):

 # DB Path definitions (NOT using SQLALCHEMY_DATABASE_URI anymore, using SQLALCHEMY_BINDS instead.)
SQLALCHEMY_BINDS = {
    'db1': 'full_path_to_db',
    'db2': 'full_path_to_db'
    }

# Models
class Table1(db.Model):
    __tablename__ = 'table1'
    __bind_key__ = 'db1'
      #column declarations
    
class Table2(db.Model):
    __tablename__ = 'table2'
    __bind_key__ = 'db2'
      #column declarations
  

Но ошибка не устраняется. Я не уверен, чего нам здесь не хватает.

Повторяю, первая / начальная миграция (и обновление) работает просто отлично. Таблицы alembic_version в обеих базах данных должным образом обновлены с правильным номером версии миграции. Но после этого, когда мы вносим какие-либо изменения в модель и требуется выполнить вторую миграцию, новый файл миграции не создается, и он выдает ошибку Целевая база данных не найдена.

Ценю помощь!

Ответ №1:

У меня тоже была такая же проблема. Моя проблема была решена, когда я применил одну базу данных с помощью SQLALCHEMY_DATABASE_URI и другой с помощью SQLALCHEMY_BINDS , а затем удалил миграции и таблицы (не подтвердите, что удаление таблицы необходимо или нет). Затем он точно выбирал все миграции без ошибок Error: Target database is not up to date . Мой предыдущий код:

 SQLALCHEMY_BINDS = {
        'central': POST_CONN_URI % POSTGRES_MAIN_DB_NAME,
        'tenant': POST_CONN_URI % 'demo_tenant'
    }
  

и новый код:

 SQLALCHEMY_DATABASE_URI = POST_CONN_URI % POSTGRES_MAIN_DB_NAME
SQLALCHEMY_BINDS = {
   'tenant': POST_CONN_URI % 'demo_tenant'
}