Flask 迁移失败

Mar*_*ark 2 flask python-3.x

不出所料,我正在 Flask 中进行迁移Flask-Migrate。一旦我执行python manage.py db init它创建migrations具有初始迁移文件的目录。然后我执行python manage.py db migrate,我得到这个:

...
...
target_metadata = current_app.extensions['migrate'].db.metadata
AttributeError: 'NoneType' object has no attribute 'metadata'
Run Code Online (Sandbox Code Playgroud)

我从这个输出中了解到 'migrate'None因此我收到一个属性错误。

模型.py:

from sqlalchemy.sql import func
from project import db, bcrypt


class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = db.Column(db.String(128), nullable=False, unique=True)
    email = db.Column(db.String(128), nullable=False, unique=True)
    password = db.Column(db.String(255), nullable=False)
    active = db.Column(db.Boolean(), default=True, nullable=False)
    created_date = db.Column(db.DateTime, default=func.now(), nullable=False)

    def __init__(self, username, email, password):
        self.username = username
        self.email = email
        self.password = bcrypt.generate_password_hash(password).decode()

    def to_json(self):
        return {
            'id': self.id,
            'username': self.username,
            'email': self.email,
            'active': self.active,
        }
Run Code Online (Sandbox Code Playgroud)

问题是为什么没有任何东西传递给它?我正在学习教程,但我不应该出现此错误。

我从类似的主题中得到了这个:

NoneType 意味着不是您认为正在使用的任何类或对象的实例,而是您实际上拥有 None。这通常意味着上面的赋值或函数调用失败或返回了意外的结果。

这是我在迁移目录中的 env.py 文件中找到的内容:

from flask import current_app
config.set_main_option('sqlalchemy.url',
                       current_app.config.get('SQLALCHEMY_DATABASE_URI'))
target_metadata = current_app.extensions['migrate'].db.metadata
Run Code Online (Sandbox Code Playgroud)

current_app正在从 Flask 导入,但不包含migrate我需要从中使用元数据的扩展名。

没有理由抛出它,None因为扩展名已在__init__.py文件中正确初始化:

...
...
from flask_migrate import Migrate

db = SQLAlchemy()
toolbar = DebugToolbarExtension()
cors = CORS()
migrate = Migrate()
bcrypt = Bcrypt()

def create_app(script_info=None):
    app = Flask(__name__)
    app_settings = os.getenv('APP_SETTINGS')
    app.config.from_object(app_settings)
    app.config.from_object('project.config.DevelopmentConfig')
    toolbar.init_app(app)
    cors.init_app(app)
    db.init_app(app)
    migrate.init_app(app)     #  <--
    bcrypt.init_app(app)

    from project.api.users import users_blueprint
    app.register_blueprint(users_blueprint)

    @app.shell_context_processor
    def ctx():
        return {'app': app, 'db': db}

    return app
Run Code Online (Sandbox Code Playgroud)

Mar*_*ark 7

我在migrate扩展的初始化中缺少一个参数。Migrate 接收app实例的实例db

def create_app(script_info=None):
    app = Flask(__name__)
    app_settings = os.getenv('APP_SETTINGS')
    app.config.from_object(app_settings)
    app.config.from_object('project.config.DevelopmentConfig')
    toolbar.init_app(app)
    cors.init_app(app)
    db.init_app(app)
    migrate.init_app(app, db)     #  <--
    bcrypt.init_app(app)

    from project.api.users import users_blueprint
    app.register_blueprint(users_blueprint)

    @app.shell_context_processor
    def ctx():
        return {'app': app, 'db': db}

    return app
Run Code Online (Sandbox Code Playgroud)