【问题标题】:Flask migration fails烧瓶迁移失败
【发布时间】:2019-09-26 13:58:13
【问题描述】:

不出所料,我正在使用 Flask-Migrate 在 Flask 中进行迁移。 一旦我执行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'

我从这个输出中了解到“迁移”是 None,因此我遇到了属性错误。

models.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,
        }

问题是为什么什么都没有传递给它?我正在学习教程,我不应该有这个错误。

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

NoneType 表示不是任何 Class 或 Object 的实例 你认为你正在使用,你实际上没有。那通常 表示上面的赋值或函数调用失败或返回 出乎意料的结果。

这是我在迁移目录的 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

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

【问题讨论】:

    标签: python-3.x flask


    【解决方案1】:

    我在 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
    

    【讨论】:

    • 谢谢!我犯了同样的错误,忘记将 db 传递给 migrate.init_app ...
    猜你喜欢
    • 2019-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-31
    • 1970-01-01
    • 2014-04-11
    • 1970-01-01
    相关资源
    最近更新 更多