Flask-Migrate 首次迁移时未检测到架构更改

Posted

技术标签:

【中文标题】Flask-Migrate 首次迁移时未检测到架构更改【英文标题】:Flask-Migrate No Changes Detected to Schema on first migration 【发布时间】:2019-01-17 21:07:18 【问题描述】:

我将 Flask 与 Flask-SQLAlchemy 和 Flask-Migrate 一起使用来创建应用程序,但是当我尝试创建迁移时没有任何反应。

我在app/models.py中创建了两个表:

from flask import current_app
from . import db

class Student(db.Model):
    __tablename__ = 'students'
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(64), unique=True, nullable=False)
    password_hash = db.Column(db.String(128))

    def __init__(self, **kwargs):
        super(Student, self).__init__(**kwargs)

    def __repr__(self):
        return '<Tutor >' % self.id

class Tutor(db.Model):
    __tablename__ = 'tutors'
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(64), unique=True, index=True)
    password_hash = db.Column(db.String(128))

    def __init__(self, **kwargs):
        super(Tutor, self).__init__(**kwargs)
    def __repr__(self):
        return '<Student %r>' % self.id

然后我也有app/__init__.py,代码如下:

from flask import Flask
from flask_bootstrap import Bootstrap
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate

#from .models import User, Task, Project, UserProject

from config import config

bootstrap = Bootstrap()
db = SQLAlchemy()
migrate = Migrate()

def create_app(config_name='default'):
    #print config_name.name
    app = Flask(__name__)
    app.config.from_object(config[config_name])
    config[config_name].init_app(app)

    bootstrap.init_app(app)
    db.init_app(app)
    migrate.init_app(app, db)

    ## Register the main blueprint for main app functionality
    from .main import main as main_blueprint
    app.register_blueprint(main_blueprint)

    return app

app.py:

import os
from app import create_app, db
from app.models import Tutor, Student

app = create_app('default')

@app.shell_context_processor
def make_shell_context():
    return dict(db=db, Tutor=Tutor, Student=Student)

我可以毫无问题地运行flask db init,它会创建迁移目录和所有必要的文件,输出如下:

Creating directory /Users/Jasmine/projects/flask/flask-tutoring/migrations ... done
Creating directory /Users/Jasmine/projects/flask/flask-tutoring/migrations/versions ... done
Generating /Users/Jasmine/projects/flask/flask-tutoring/migrations/script.py.mako ... done
Generating /Users/Jasmine/projects/flask/flask-tutoring/migrations/env.py ... done
Generating /Users/Jasmine/projects/flask/flask-tutoring/migrations/README ... done
Generating /Users/Jasmine/projects/flask/flask-tutoring/migrations/alembic.ini ... done
Please edit configuration/connection/logging settings in '/Users/Jasmine/projects/flask/flask-tutoring/migrations/alembic.ini' before proceeding.

但是当我尝试运行flask db migrate 时,alembic 无法检测到我在app/models.py 中有表格。我得到以下输出:

INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.env] No changes in schema detected.

没有创建迁移脚本,好像models.py 不存在。

抱歉,如果这是一个重复的问题,但我找不到另一个示例,它的第一次迁移失败并且根本没有创建迁移脚本。

我尝试通过在 shell 中运行 db.drop_all() 来检查是否已经在某处创建了一个表,但这似乎不是问题。

更新

我自己想出了一种方法来解决这个问题,但想更好地理解为什么会这样。

我将 app.py 重命名为 flasktutor.py 并重新运行 export FLASK_APP='flasktutor.py'。随后迁移工作完美。

请有人解释为什么当文件被称为 app.py 而我使用 export FLASK_APP='app.py' 时,迁移没有注册对架构的更改。

【问题讨论】:

您还必须更改其他内容。我有一个名为 app.py 的应用程序,我用它来测试 Flask-Migrate,它运行良好。如果你有一个完整的例子来说明这个问题,如果你能分享它将会很有用。 我也有同样的问题,但我的文件名为 run.py。我将其更改为 app.py,然后更改为 phoenix.py,但仍然是同样的问题。在此行上调试应用程序app.config.from_object(app_config[config_name]) 我发现当我运行应用程序时,对 config_name 的引用会引发相同的错误。 KeyError: &lt;flask.cli.ScriptInfo object at 0x0000000003A11D68&gt;. 这是我遇到的一个问题,谢谢,这与烧瓶在不同点混合了同名的包和模块导入有关 【参考方案1】:

我遇到了这个问题并通过在以下 cmets 之后将我的模型导入到迁移文件夹中的 env.py 来解决它

# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata

from app.models import Student, Tutor

【讨论】:

【参考方案2】:

请确保您在 migrate.init_app(app, db) 之前已导入您的模型(导师、学生...)

【讨论】:

【参考方案3】:

这就是我解决问题的方法:

    导入Migrate模型:from flask_migrate import Migrate 发起Migrate类:migrate = Migrate(app, db) 评论db.create_all() 立即删除您的数据库 => DROP DATABASE db_name; 再次创建 => CREATE DATABSE db_name OWNER owner_name; 导出烧瓶入口文件 => export FLASK_APP=name_app.py 运行flask db migrate

注意:如果出现此错误,应使用第 6 步:

Error: Could not locate a Flask application

希望这会对某人有所帮助。

【讨论】:

谢谢你告诉我必须评论db.create_all()【参考方案4】:

我在Miguel's great tutorial 之后遇到了同样的问题,这里的提示非常有帮助!

我的解决方案 - 不需要 需要“黑客”env.py - 只需添加

from app import models

__init__.py

如果您有不同的项目布局,您可能需要调整导入,但您似乎需要确保模型正确导入,flask db migrate 才能正常工作。

【讨论】:

【参考方案5】:

嗯,我在学习 Miguel Grinberg 教程后遇到了同样的问题。

之前我使用 shell 调用创建了表

db.create_all()

所以,我想放弃表格

db.drop_all()

再次尝试迁移命令,它按预期工作:

Roberto@MyPC MINGW64 /e/Projects/Flask/flasky ((5c))
$ flask db migrate -m "initial migration - Role Users"
INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.autogenerate.compare] Detected added table 'roles'
INFO  [alembic.autogenerate.compare] Detected added table 'users'
INFO  [alembic.autogenerate.compare] Detected added index 'ix_users_username' on '['username']'
Generating E:\Projects\Flask\flasky\migrations\versions\4de323c9c089_initial_migration_role_users.py ... done

之后,我使用 flask-migrate 重新创建表

$ flask db upgrade
INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.runtime.migration] Running upgrade  -> b641ee80a60d, initial migration - Role Users

【讨论】:

【参考方案6】:

我在学习 Miguel Grinberg 教程时遇到了同样的问题。 我解决了这个我的添加

from app.models import  User, Post

迁移到迁移/env.py

【讨论】:

然后重新运行flask db migrate -m "users table"【参考方案7】:

这对我有用:

migrations/env.py 中,导入您的模型

# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
from app.models import * # <= Add this line
from flask import current_app

【讨论】:

【参考方案8】:

flask-migrate 在您更改表架构后工作。

如之前:

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy(app)

class Test(db.Model):
    content = db.Column(db.String(60))

然后您更改您的测试架构,例如:

class Test(db.Model):
    content = db.Column(db.String(60))
    add = db.Column(db.String(60))

现在,您可以使用flask db migrate -m "migrate test" 工作了。

您将获得迁移版本信息。

【讨论】:

【参考方案9】:

你可以只指向空数据库来创建迁移文件,然后返回升级你的真实数据库。

【讨论】:

【参考方案10】:

在尝试修复它并阅读了一段时间后,我刚刚删除了迁移目录(文件夹)和 app.db。 然后又跑了:

    “烧瓶数据库初始化” “烧瓶数据库迁移” “烧瓶数据库升级”

这会重新生成目录,现在一切正常。

如果您想改进您的迁移脚本,这个指向 Miguel 升级的链接会很有用:https://www.youtube.com/watch?v=wpRVZFwsD70&feature=emb_logo

【讨论】:

以上是关于Flask-Migrate 首次迁移时未检测到架构更改的主要内容,如果未能解决你的问题,请参考以下文章

Flask 学习-15.flask-migrate数据迁移

Flask从入门到精通之使用Flask-Migrate实现数据库迁移

Flask中使用Flask-Migrate扩展迁移数据库

Flask之flask-migrate 数据库迁移

Flask 数据库迁移

flask-migrate