26

我在文件中有以下模型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 initthen ./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 ###

运行.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

更新

如果我通过运行 shell ./run.py 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> 

不幸的是,迁移仍然不起作用。

4

6 回答 6

20

确保在manage.py文件(或带有迁移实例的文件)中导入模型。您必须在文件中导入模型,即使您没有明确使用它们。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()
于 2017-05-25T13:12:32.813 回答
19

当您调用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

尝试重新结帐,我认为您的设置是正确的。

于 2013-10-11T17:37:53.730 回答
11

我有同样的问题,但不同的问题导致了它。Flask-migrate 工作流程由两个后续命令组成:

flask db migrate

这会产生迁移和

flask db upgrade

它应用了迁移。我忘记运行最后一个,并尝试在不应用前一个的情况下开始下一次迁移。

于 2018-03-25T15:42:05.087 回答
8

我刚刚遇到了类似的问题。我想为遇到此线程的其他人分享我的解决方案。对我来说,我把我的模型放在一个包里。例如models/user.py,我尝试from app.models import *了在迁移时没有检测到任何内容。但是,如果我将导入更改为from app.models import userthis 就可以了,为什么我的项目还很年轻,但是由于我有更多模型,所以最好使用批量导入。

于 2013-10-22T05:01:37.130 回答
8

对于遇到此问题的任何人,我的问题是

db.create_all()

在我的主烧瓶应用程序文件中,它在没有 alembic 知识的情况下创建了新表

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

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

这次 alembic 检测到了新表并创建了一个适当的迁移脚本

于 2016-11-10T00:26:51.597 回答
1

对我来说奇怪的解决方案是:删除数据库和文件夹migrations。然后

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

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

于 2018-12-13T16:21:58.843 回答