Flask迁移,首次迁移时未检测到对架构的更改

时间:2018-08-10 09:27:37

标签: python-3.x flask flask-sqlalchemy flask-migrate

我将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,它会创建Migrations目录和所有必需的文件,并显示以下内容:

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不存在。

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

我尝试通过在外壳程序中运行db.drop_all()来检查是否已在某处创建表,但这似乎不是问题。

更新

我想出了一种自行解决此问题的方法,但想更好地理解为什么这样做。

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

请有人可以解释为什么当文件名为app.py且我使用export FLASK_APP='app.py'时,迁移未将更改注册到架构中。

10 个答案:

答案 0 :(得分:4)

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

  1. 导入迁移模型:from flask_migrate import Migrate
  2. 启动迁移类:migrate = Migrate(app, db)
  3. 评论db.create_all()
  4. 立即删除您的数据库=> DROP DATABASE db_name;
  5. 再次创建=> CREATE DATABSE db_name OWNER owner_name;
  6. 导出烧瓶输入文件=> export FLASK_APP=name_app.py
  7. 运行flask db migrate

注意:如果您可能会遇到此错误,请使用第六步:Error: Could not locate a Flask application

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

答案 1 :(得分:2)

在Miguel Grinberg教程之后,我遇到了相同的问题。 我解决了我的添加问题

from app.models import  User, Post

到migrations / env.py

答案 2 :(得分:1)

我遇到了此问题,并通过在以下注释后立即将我的模型导入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 Student, Tutor

答案 3 :(得分:1)

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

我的解决方案 - 不需要 hack env.py - 是简单地添加

from app import models

__init__.py

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

答案 4 :(得分:0)

请确保您已经在migrate.init_app(app, db)之前导入了模型(教师,学生等)

答案 5 :(得分:0)

好吧,在Miguel Grinberg教程之后,我遇到了同样的问题。

以前,我是使用shell调用创建表的

db.create_all()

所以,我很想丢桌子

db.drop_all()

并再次尝试migration命令,它按预期工作:

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 :(得分:0)

在您更改表架构后,flask迁移才能工作。

例如,之前:

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"进行工作了。

您将获得迁移版本信息。

答案 7 :(得分:0)

这对我有用:

migrations / env.py 中,导入模型

(.+),(.+)@(.+)           // works when the string is complete
                         //  but how do you express the optionality?
(.+),?(.+)@?(.+)         // nope
(.*)[$,](.*)[$@](.*)     // neither

答案 8 :(得分:0)

您只能指向空数据库以创建迁移文件,然后返回以升级实际数据库。

答案 9 :(得分:0)

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

  1. “烧瓶数据库初始化”
  2. “烧瓶数据库迁移”
  3. “烧瓶数据库升级”

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

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