Flask-миграция изменить базу данных перед обновлением

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

Я использую Flask-Script с Flask-Migrate для обработки миграции.

До сих пор я пробовал перебирать имена схем, создавать для них URI, определять область действия нового db.session с помощью механизма, сгенерированного из URI, и, наконец, запускать функцию обновления из flask_migrate.

    @manager.command
    def upgrade_all_clients():
        clients = clients_model.query.all()
        for c in clients:
            application.extensions["migrate"].migrate.db.session.close_all()
            application.extensions["migrate"].migrate.db.session = db.create_scoped_session(
                options={
                    "bind": create_engine(generateURIForSchema(c.subdomain)),
                    "binds": {},
                }
            )
            upgrade()
        return

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

Моя теория заключается в том, что я не меняю сеанс, который был изначально установлен при запуске сценария менеджера.

Есть ли лучший способ перенести каждую из этих схем без установки нескольких привязок и использования параметра --multidb? Я не думаю, что смогу использовать SQLALCHEMY_BINDS в конфигурации, поскольку эти схемы должны иметь возможность динамически создаваться/удаляться.


person HomestuckBrother    schedule 12.11.2020    source источник


Ответы (1)


Для тех, кто сталкивается с той же проблемой, ответ на мою конкретную ситуацию был невероятно простым.

@manager.command
def upgrade_all_clients():
    clients = clients_model.query.all()
    for c in clients:
        print("Upgrading client '{}'...".format(c.subdomain))
        db.engine.url.database = c.subdomain
        _upgrade()
    return

Атрибут базы данных db.engine.url — это то, что нацелено на схему. Я не знаю, лучший ли это способ решить эту проблему, но он работает, и я могу перенести каждую схему по отдельности.

person HomestuckBrother    schedule 13.11.2020