web-dev-qa-db-ja.com

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/__ 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_を介してシェルを実行し、次に_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> 
_

残念ながら、移行はまだ機能しません。

21
Mark Richman

migrateコマンドを呼び出すと、Flask-Migrate(または実際にはその下のAlembic)が_models.py_を調べ、それを実際にデータベースにあるものと比較します。

空の移行スクリプトがあるという事実は、おそらくFlask-SQLAlchemyのdb.create_all()を呼び出すことによって、Flask-Migrateの制御外にある別のメソッドを通じてモデルに一致するようにデータベースを更新したことを示唆しています。

データベースに貴重なデータがない場合は、Pythonシェルを開き、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
_

新しいチェックアウトを試してください。あなたの設定は正しいと思います。

15
Miguel

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()
14
wcyn

同じ問題がありましたが、別の問題が原因でした。 Flask-migrateワークフローは、次の2つのコマンドで構成されます。

flask db migrate

移行を生成し、

flask db upgrade

移行を適用します。最後のものを実行するのを忘れて、前のものを適用せずに次の移行を開始しようとしました。

8
Dany

同様の問題が発生しました。このスレッドに遭遇した他の人のために私の解決策を共有したいと思います。私は、モデルをパッケージに入れていました。たとえば、models/user.pyと私はfrom app.models import *を試してみましたが、移行時に何も検出されませんでした。ただし、インポートをfrom app.models import userに変更した場合、これは私のプロジェクトが若い理由で大丈夫ですが、モデルが多いため、一括インポートが推奨されます。

7
matchew

これに遭遇した人にとって、私の問題は

db.create_all()

私のメインflaskアレンビックの知識なしで新しいテーブルを作成したアプリケーションファイル

単にコメント化するか、完全に削除して、今後の移行に影響を与えないようにします。

しかし、@ Miguelの提案とは異なり、データベース全体を削除する代わりに(重要な情報が含まれていました)、Flask SQLAlchemyによって作成された新しいテーブルを削除してから移行を実行することで修正できました。

そして今回はalembicが新しいテーブルを検出し、適切な移行スクリプトを作成しました

5
danidee

私にとって奇妙な解決策は、データベースとフォルダーmigrationsを削除することです。その後

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

flask db initまたはpython app.py db initの後、flask db migrateまたはpython app.py db migrate。うわー、それは奇妙ですが、私にとってはうまくいきます。

1
kot_mapku3