【问题标题】:Flask-Migrate not creating tablesFlask-Migrate 不创建表
【发布时间】:2013-10-19 21:05:57
【问题描述】:

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

更新

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

很遗憾,迁移仍然无法正常工作。

【问题讨论】:

    标签: python flask flask-sqlalchemy flask-migrate


    【解决方案1】:

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

    【讨论】:

    • 多么美好的一天
    【解决方案2】:

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

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

    在flask db init 或python app.py db init 之后,然后是flask db migrate 或python app.py db migrate。哇,这很奇怪,但它对我有用。

    【讨论】:

      【解决方案3】:

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

      flask db migrate
      

      生成迁移和

      flask db upgrade
      

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

      【讨论】:

      • 这是给我的!我是第一次设置这个,在我遵循的教程中没有任何地方可以使用这个命令。
      【解决方案4】:

      确保在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()
      

      【讨论】:

      • 我正在关注这个例子(在没有它开始之后)并且遇到了同样的问题。realpython.com/blog/python/…作者实际上在后面的课程中解决了这个问题,所以他们没有意识到发生了什么 - 这个是正确的答案。
      • 从哪里导入 Manage(app)?
      • 导入模型解决了我的问题!谢谢!
      【解决方案5】:

      对于遇到这种情况的任何人,我的问题是

      db.create_all()

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

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

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

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

      【讨论】:

        【解决方案6】:

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

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

        【讨论】:

        • 我删除了app.db 和migrations 目录,然后重复了这个过程。同样的效果:(paste2.org/1Vf7Ixyb
        • 您能否将run.py 和listpull/__init__.py 文件添加到您的问题中?
        • 嗯。除非您的配置指向其他地方的现有 sqlite 数据库,否则我无法真正发现任何错误。你会碰巧在 github 上或某个我可以下载并试用的地方有这个应用程序吗?
        • 当然,使用github.com/mrichman/nhs-listpull,但您需要一个config.py,我在.gitignore 中包含此行:SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(_basedir, 'app.db')
        • 我更新了它以证明架构确实是通过 shell 创建的,但迁移仍然不起作用。
        猜你喜欢
        • 2021-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-31
        • 1970-01-01
        • 2020-06-01
        • 2018-09-15
        • 1970-01-01
        相关资源
        最近更新 更多