Flask-Migrate不创建表

时间:2013-10-11 17:30:04

标签: python flask flask-sqlalchemy flask-migrate

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

不幸的是,迁移仍然无效。

6 个答案:

答案 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 initpython app.py db init之后,然后在flask db migratepython app.py db migrate之后。哇,很奇怪,但是对我有用。