首页 文章

Flask-Migrate不创建表

提问于
浏览
17

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

UPDATE

如果我通过 ./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 回答

  • 6

    当您调用 migrate 命令Flask-Migrate(或其下面的实际Alembic)时,将查看您的 models.py 并将其与数据库中的实际内容进行比较 .

    事实上你可以通过调用Flask-SQLAlchemy的 db.create_all() 来控制它 .

    如果数据库中没有任何有 Value 的数据,则打开Python shell并调用 db.drop_all() 将其清空,然后再次尝试自动迁移 .

    UPDATE :我在这里安装了您的项目并确认迁移对我来说运行正常:

    (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
    

    尝试新结账,我认为您的设置是正确的 .

  • 8

    确保导入 manage.py 文件(或包含migrate实例的文件)中的Models . 您必须在文件中导入模型,即使您没有明确使用它们也是如此 . 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()
    
  • 4

    我刚遇到类似的问题 . 我想为遇到这个帖子的其他人分享我的解决方案 . 对我来说,我把我的模特放在一个包里 . 例如models / user.py和我尝试 from app.models import * ,它没有检测到迁移上的任何内容 . 但是,如果我将导入更改为 from app.models import user 这是可以的,为什么我的项目很年轻,但是因为我有更多的模型,所以批量导入会更好 .

  • 5

    我有同样的问题,但是一个不同的问题引起了它 . Flask-migrate工作流包含两个后续命令:

    flask db migrate
    

    它产生迁移和

    flask db upgrade
    

    适用于迁移 . 我忘了运行最后一个,并尝试在不应用前一个迁移的情况下开始下一个迁移 .

  • 0

    对于遇到此问题的人来说,我的问题就在于此

    db.create_all()

    在我的主烧瓶应用程序文件中创建了新表而不知道alembic

    只需将其注释掉或完全删除它,这样就不会破坏未来的迁移 .

    但不像@ Miguel的建议,我没有删除整个数据库(我有重要信息),而是通过删除Flask SQLAlchemy创建的新表然后运行迁移来修复它 .

    而这次alembic检测到新表并创建了一个正确的迁移脚本

  • 13

    奇怪的解决方法是:删除数据库和文件夹 migrations . 然后

    >>> from app import db
    >>> db.create_all()
    

    flask db initpython app.py db init 然后 flask db migratepython app.py db migrate 之后 . 哇,这很奇怪,但它对我有用 .

相关问题