2013-06-19 11 views
10

私はAlembicを使用してFlaskのマイグレーションを処理しています。 alembic revision --autogenerateは、理論上、自分のデータベースの変更に基づいてマイグレーションを自動生成する必要があります。しかし、Alembicは単に上記のコマンドで空白の移行を生成しています。Alembicは空のFlask-SQLAlchemyマイグレーションを自動生成します

question very similar to this oneがあります。ここでは、適切なモデルがインポートされていないという問題がありました。 env.pyに示すように、しかし、私は、私のフラスコアプリからモデルをインポートしている:

... 
# import settings from Flask 
alembic_config = config.get_section(config.config_ini_section) 
from start import app 
from models import User, Item, Recipient # models are imported here from models.py 
alembic_config['sqlalchemy.url'] = app.config['SQLALCHEMY_DATABASE_URI'] 

engine = engine_from_config(
      alembic_config, # config.get_section(config.config_ini_section) 
      prefix='sqlalchemy.', 
      poolclass=pool.NullPool) 
... 

と同様にenv.pyで輸入DBのメタデータを(「開始」を私のフラスコアプリのメインファイルの名前です)

... 
from start import db 
target_metadata = db.metadata 
... 

私のフラスコアプリは不賛成だろうが、空の移行を生成し、その後alembic revision --autogenerate -m "initial_rev"を実行:

"""initial_rev 

Revision ID: 45296fd29540 
Revises: None 
Create Date: 2013-06-19 17:32:38.392268 

""" 

# revision identifiers, used by Alembic. 
revision = '45296fd29540' 
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 ### 

編集

私のアプリのファイル構造といくつかの追加コードを示しています。問題は、Alembicがからインポートされたdbを最初に__init__.pyに初期化せずに持っていないことが問題だと思われます。しかし、これは不可能青写真が使用される場合(循環輸入のため)、このSO答えで説明されています:https://stackoverflow.com/a/9695045/353878

Flaskの青写真が使用されているときには、どうしたらAlembicを使用できますか?

編集#2

私も、データベースのメタデータが正しくインポートされていたことを確認するために、db.metadata.sorted_tablesを印刷してみました。確かに、データベーススキーマ全体が端末にパイプされていました。では、なぜAlembicはブランクのアップグレード/ダウングレード機能を生成していますか?

編集#3

私は問題がdb.init_app(app)db = SQLAlchemy(app)の違いとは何かを持っていると結論付けましたが、私は問題を引き起こしているものはかなりよく分かりません。この理論をテストするために、env.pyfrom database import dbdb = SQLAlchemy(app)に置き換えました。おそらく悪い考えですが、私はデバッグのために何が起こるのかを見たいと思っていました。

Alembicは、upgrade()およびdowngrade()メソッドを自動生成して埋めましたが、それらは逆でした! upgrade()はすべてのテーブルを削除しましたが、downgrade()はすべての適切な列とメタデータでテーブルを作成しました。なぜこれがあるのか​​わかりませんが、この問題を理解しようとしている人には役立つことを願っています。

+0

'alembic revision --autogenerate'を実行したときにスキーマがどのように変更されましたか? – drewman

+0

私はいくつかの列を持つ3つのテーブルを追加しました。 – element119

+0

'env.py'でモデルをインポートしてメタデータに登録する必要があります。 – iElectric

答えて

23

フレンチと青写真でアレムビアを使用する方法は次のとおりです。

https://github.com/davidism/basic_flask

私は、アプリケーションファクトリパターンを使用し、その内db.init_appを呼び出します。 db = SQLAlchemy()の後にサブタイプdb.Modelのすべてのモデルをインポートしてdb.metadataがそれらを認識するようにします。これはcreate_app工場では行われませんが、モジュールの初期化中はインラインで行われることに注意してください。

alembicを実行している場合、プロジェクトフォルダはsys.pathに含まれていませんので、設定します。その後、私は工場からアプリを作成し、その設定からsqlalchemy.urlを設定します。また、dbをインポートし、target_metadata = db.metadataと設定します。

この設定は、プロジェクトの構造に関係なく常に私のために機能します。私は非常に基本的な一連のユーザーモデルと、青写真のあるサブパッケージに非常に愚かなビューを含んでいました。 relaventモデルをload_modelsにロードし、青写真を定義した後にビューをインポートし、青写真をinit_viewsにインポートしてください。

+0

お返事ありがとうございました!あなたが提案した変更を行ってみましたが、私は2つの質問があります:init_views()はいつ呼ばれますか?また、この設定では、どのようにappwideメソッド(たとえば@ app.before_requestなど)を使用していますか? – element119

+0

@autibyte 'init_views'は' create_app'で呼び出されます。 'init_views'と同様に、' init_helpers'を作成して、アプリケーションの作成時にそれらを登録することができます。 – davidism

関連する問題