如何使用Flask和Sqalchemy自动创建数据库表和架构?

时间:2020-03-26 20:43:19

标签: python flask sqlalchemy flask-sqlalchemy

我有一个小的Flask应用程序。我添加了一个额外的安全层,用于登录。我的重构基于DO article

简而言之,

__init__.py

from flask import Flask
from flask_login import LoginManager
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash
from sqlalchemy import create_engine

# init SQLAlchemy so we can use it later in our models
db = SQLAlchemy()

def create_app():
    app = Flask(__name__)

    app.config['SECRET_KEY'] = 'e56432f4402c9a0c166fe6c6a0a2fbbd'
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite'

    db.init_app(app)

        # blueprint for auth routes in our app
    from .auth import auth as auth_blueprint
    app.register_blueprint(auth_blueprint)

    # blueprint for non-auth parts of app
    from .main import main as main_blueprint
    app.register_blueprint(main_blueprint)

    login_manager = LoginManager()
    login_manager.login_view = 'auth.login'
    login_manager.init_app(app)

    from .models import User

    @login_manager.user_loader
    def load_user(user_id):
        # since the user_id is just the primary key of our user table, use it in the query for the user
        return User.query.get(int(user_id))

    return app

为了创建数据库,我需要在REPL中运行:

  from project import db, create_app
  db.create_all(app=create_app())

这既不方便,又使Docker映像创建更加困难。我以flask run的身份运行应用程序。我看到了类似的问题,但不了解如何将其应用于我的方案。

如何克服这种并发症?

更新1:

我的项目结构如下:

project/
  project/
    __init__.py
    auth.py
    main.py
    models.py
    static/
    templates/
  Dockerfile
  requirements.txt

2 个答案:

答案 0 :(得分:0)

如果要在运行flask应用程序时创建数据库:

我会输入这段代码

def createMyDatabase():
    from project import db, create_app
    db.create_all(app=create_app())

进入文件makedatabase.py,并将其保存到程序的根目录中。然后将from <path to makedatabase.py>/makedatabase import createMyDatabase添加到__init__.py文件的顶部,然后在__init__.py中的import语句之后,写createMyDatabase()。我认为这将是您遇到的最简单的方法。

如果您不想在每次运行程序时都创建数据库:

您可以只将函数从makedatabase.py文件中取出,然后按原样运行该文件,然后再运行flask应用程序。

答案 1 :(得分:0)

我找到了一个更优雅的解决方案

而不是return app进行以下阻止,因此,当且仅当初始化上下文并创建数据库时,才会在运行时创建应用程序。

with app.app_context():
        db.create_all()
        return app

令人惊讶的是,Flask-SqlAlchemy指出创建REPL数据库是第一个解决方案,而不是上面的解决方案。

相关问题