我在文件listpull/models.py
中有以下模型:
from datetime import datetime
from listpull import db
class Job(db.Model):
id = db.Column(db.Integer, primary_key=True)
list_type_id = db.Column(db.Integer, db.ForeignKey('list_type.id'),
nullable=False)
list_type = db.relationship('ListType',
backref=db.backref('jobs', lazy='dynamic'))
record_count = db.Column(db.Integer, nullable=False)
status = db.Column(db.Integer, nullable=False)
sf_job_id = db.Column(db.Integer, nullable=False)
created_at = db.Column(db.DateTime, nullable=False)
compressed_csv = db.Column(db.LargeBinary)
def __init__(self, list_type, created_at=None):
self.list_type = list_type
if created_at is None:
created_at = datetime.utcnow()
self.created_at = created_at
def __repr__(self):
return '<Job {}>'.format(self.id)
class ListType(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), unique=True, nullable=False)
def __init__(self, name):
self.name = name
def __repr__(self):
return '<ListType {}>'.format(self.name)
我呼叫./run.py init
然后./run.py migrate
然后./run.py upgrade
,我看到生成的迁移文件,但它是空的:
"""empty message
Revision ID: 5048d48b21de
Revises: None
Create Date: 2013-10-11 13:25:43.131937
"""
# revision identifiers, used by Alembic.
revision = '5048d48b21de'
down_revision = None
from alembic import op
import sqlalchemy as sa
def upgrade():
### commands auto generated by Alembic - please adjust! ###
pass
### end Alembic commands ###
def downgrade():
### commands auto generated by Alembic - please adjust! ###
pass
### end Alembic commands ###
run.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from listpull import manager
manager.run()
listpull / __初始化__。PY
# -*- coding: utf-8 -*-
# pylint: disable-msg=C0103
""" listpull module """
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.script import Manager
from flask.ext.migrate import Migrate, MigrateCommand
from mom.client import SQLClient
from smartfocus.restclient import RESTClient
app = Flask(__name__)
app.config.from_object('config')
db = SQLAlchemy(app)
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
mom = SQLClient(app.config['MOM_HOST'],
app.config['MOM_USER'],
app.config['MOM_PASSWORD'],
app.config['MOM_DB'])
sf = RESTClient(app.config['SMARTFOCUS_URL'],
app.config['SMARTFOCUS_LOGIN'],
app.config['SMARTFOCUS_PASSWORD'],
app.config['SMARTFOCUS_KEY'])
import listpull.models
import listpull.views
更新
如果我通过./run.py shell
运行shell然后执行from listpull import *
并调用db.create_all()
,我会获得架构:
mark.richman@MBP:~/code/nhs-listpull$ sqlite3 app.db
-- Loading resources from /Users/mark.richman/.sqliterc
SQLite version 3.7.12 2012-04-03 19:43:07
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .schema
CREATE TABLE job (
id INTEGER NOT NULL,
list_type_id INTEGER NOT NULL,
record_count INTEGER NOT NULL,
status INTEGER NOT NULL,
sf_job_id INTEGER NOT NULL,
created_at DATETIME NOT NULL,
compressed_csv BLOB,
PRIMARY KEY (id),
FOREIGN KEY(list_type_id) REFERENCES list_type (id)
);
CREATE TABLE list_type (
id INTEGER NOT NULL,
name VARCHAR(80) NOT NULL,
PRIMARY KEY (id),
UNIQUE (name)
);
sqlite>
不幸的是,迁移仍然无效。
答案 0 :(得分:13)
当您调用migrate
命令Flask-Migrate(或其下面的实际Alembic)时,将查看您的models.py
并将其与数据库中的实际内容进行比较。
您有一个空的迁移脚本这一事实表明您已经通过Flask-Migrate控制之外的另一种方法更新了数据库以匹配您的模型,可能是通过调用Flask-SQLAlchemy的db.create_all()
。
如果您的数据库中没有任何有价值的数据,请打开Python shell并调用db.drop_all()
将其清空,然后再次尝试自动迁移。
更新:我在这里安装了您的项目并确认迁移对我来说运行良好:
(venv)[miguel@miguel-linux nhs-listpull]$ ./run.py db init
Creating directory /home/miguel/tmp/mark/nhs-listpull/migrations...done
Creating directory /home/miguel/tmp/mark/nhs-listpull/migrations/versions...done
Generating /home/miguel/tmp/mark/nhs-listpull/migrations/script.py.mako...done
Generating /home/miguel/tmp/mark/nhs-listpull/migrations/env.pyc...done
Generating /home/miguel/tmp/mark/nhs-listpull/migrations/env.py...done
Generating /home/miguel/tmp/mark/nhs-listpull/migrations/README...done
Generating /home/miguel/tmp/mark/nhs-listpull/migrations/alembic.ini...done
Please edit configuration/connection/logging settings in
'/home/miguel/tmp/mark/nhs-listpull/migrations/alembic.ini' before
proceeding.
(venv)[miguel@miguel-linux nhs-listpull]$ ./run.py db migrate
INFO [alembic.migration] Context impl SQLiteImpl.
INFO [alembic.migration] Will assume non-transactional DDL.
INFO [alembic.autogenerate] Detected added table 'list_type'
INFO [alembic.autogenerate] Detected added table 'job'
Generating /home/miguel/tmp/mark/nhs-
listpull/migrations/versions/48ff3456cfd3_.py...done
尝试新结帐,我认为您的设置正确。
答案 1 :(得分:10)
确保导入manage.py
文件(或包含migrate实例的文件)中的模型。您必须在文件中导入模型,即使您没有明确使用它们也是如此。 Alembic需要迁移这些导入,并在数据库中创建表。例如:
# ... some imports ...
from api.models import User, Bucketlist, BucketlistItem # Import the models
app = create_app('dev')
manager = Manager(app)
migrate = Migrate(app, db)
manager.add_command('db', MigrateCommand)
# ... some more code here ...
if __name__ == "__main__":
manager.run()
db.create_all()
答案 2 :(得分:7)
我刚遇到类似的问题。我想为遇到这个帖子的其他人分享我的解决方案。对我来说,我把我的模特放在一个包里。例如models / user.py和我尝试了from app.models import *
,它没有检测到任何迁移。但是,如果我将导入更改为from app.models import user
,这可以解释为什么我的项目很年轻,但由于我有更多模型,因此批量导入会更好。
答案 3 :(得分:7)
我有同样的问题,但是一个不同的问题导致了它。 Flask-migrate工作流程包含两个后续命令:
flask db migrate
生成迁移和
flask db upgrade
应用迁移。我忘了运行最后一个并试图开始下一次迁移而不应用前一个。
答案 4 :(得分:5)
对于遇到这种情况的人来说,我的问题是
db.create_all()
在我的主要烧瓶申请文件中 在不知道alembic的情况下创建了新表
只需将其评论或完全删除即可,以免日后的迁移工作陷入困境。
但不像@ Miguel的建议,我没有删除整个数据库(我有重要信息),而是通过删除Flask SQLAlchemy创建的新表然后运行迁移来修复它。 / p>
这次alembic检测到新表并创建了正确的迁移脚本
答案 5 :(得分:0)
对我来说奇怪的解决方法是:删除数据库和文件夹migrations
。然后
>>> from app import db
>>> db.create_all()
在flask db init
或python app.py db init
之后,然后在flask db migrate
或python app.py db migrate
之后。哇,很奇怪,但是对我有用。