Flask-migrate 升级失败,因为应用程序需要在启动时运行修改数据库的代码

问题描述 投票:0回答:2

我有一个 Flask 应用程序需要在启动时运行代码。就我而言,它会检测可用的云资源并将其写入数据库中的表中。

问题是,当我运行

flask db upgrade
时,flask-migrate会执行应用程序启动代码,包括尝试写入数据库表的代码。由于迁移本身就是创建表的过程,因此该表还不存在,迁移失败。

这是代码,删除了不相关的部分:

def create_app():
    app = Flask(__name__, static_url_path=None)
    with app.app_context():
        db = set_up_database_connection()

    Migrate(app, db)
    
    # This is what fails because the table doesn't exist yet
    run_startup_tasks()

    @app.get('/')
    def health_check():
        return 'OK'

    app.logger.info("Application created.")
    return app

我使用

@app.before_first_request
注释做了一个临时解决方法。通过解决方法,启动代码将在第一个请求通过之前运行。但这并不理想,因为这会导致对应用程序的第一个请求需要很长时间。

 @app.before_first_request
 def perform_startup_tasks():
     run_startup_tasks()

如何在不破坏flask-migrate的情况下运行需要数据库的启动任务?

python flask flask-migrate
2个回答
0
投票

我最终通过创建一个单独的文件来解决这个问题,该文件运行启动任务:

app = Flask(__name__, static_url_path=None)
with app.app_context():
    db = set_up_database_connection()

run_startup_tasks()

此文件在主应用程序运行之前和迁移运行之后运行:

flask db upgrade && python run_startup_tasks.py && flask run

这解决了问题,因为主应用程序(flask-migrate 使用的)不运行启动任务。它在单独的脚本中运行。


0
投票

可能会稍晚一些,但如果有人需要另一个解决方案:如

sys.argv
是一个
list[str]
,其中包含用于执行应用程序的所有命令行参数,您只需测试命令名称即可确定它是否已运行、迁移、升级或其他任何操作:

include sys

# This will always execute
print("hello world")

if not 'run' in sys.argv:
    # This will not execute when 'flask run ...' is used
    print("not run")

if not 'upgrade' in sys.argv:
    # This will not execute when 'flask db upgrade' is used
    print("not upgrade")
© www.soinside.com 2019 - 2024. All rights reserved.