2013-06-19 65 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進口分貝的元數據(「開始」是我的瓶應用程序的主文件的名稱):

... 
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 ### 

編輯

Here is a gist顯示我的應用程序的文件結構,以及一些額外的代碼。看起來問題在於,Alembic不喜歡從database.py導入數據庫,而沒有在__init__.py中首先進行初始化。但是,這是不可能的當藍圖使用(因爲週期性進口),在這個SO解釋回答:https://stackoverflow.com/a/9695045/353878

所以問題是,如何使用Flamb藍圖時也可以使用Alembic?

編輯#2

我甚至嘗試打印db.metadata.sorted_tables,以確保數據庫的元數據正在正確導入。果然,整個數據庫模式都被傳送到終端。那麼爲什麼Alembic會生成空白升級/降級功能?

編輯#3

我已經得出結論,這個問題有什麼做的db.init_app(app)db = SQLAlchemy(app)的差異,但我不能肯定是什麼原因造成的問題。爲了測試這個理論,我將env.py中的from database import db替換爲db = SQLAlchemy(app)。可能是一個糟糕的主意,但我想看看調試目的會發生什麼。

Alembic自動生成並填充了升級()和降級()方法 - 除了它們被顛倒! upgrade()刪除了我所有的三個表格,而downgrade()用所有正確的列和元數據創建了它們。我不知道這是爲什麼,但我希望對試圖找出這個問題的人有幫助。

+0

當你運行'alembic revision --autogenerate'時,你的模式有什麼變化? – drewman

+0

我已經添加了幾個列的三個表。 – element119

+0

您必須在'env.py'中導入模型,以便它們註冊到元數據中。 – iElectric

回答

23

這是我如何使用Alembic與燒瓶和藍圖。

https://github.com/davidism/basic_flask

我使用的應用程序工廠模式,並調用內db.init_appdb = SQLAlchemy()之後,我導入所有將繼承db.Model的模型,以便db.metadata知道它們;請注意,這不是在create_app工廠中完成的,而是在模塊初始化期間內聯。

當運行alembic時,項目文件夾不包含在sys.path中,所以我設置了它。然後我從工廠創建一個應用程序,並從其配置中設置sqlalchemy.url。另外,我輸入db並設置target_metadata = db.metadata

無論項目結構如何,此設置都適用於我。我在一個包含藍圖的子包中包含了一組非常基本的用戶模型和非常愚蠢的視圖。只需確保在load_models中加載相關模型,定義藍圖後導入視圖,然後導入init_views中的藍圖。

+0

非常感謝您的回答!我試着做你提出的改變,但我有兩個問題:何時調用init_views()?此外,使用此設置,您還有哪些應用範圍的方法(例如@ app.before_request)? – element119

+0

@autibyte''init_views'在'create_app'中被調用。與'init_views'類似,您可以創建'init_helpers'來註冊創建應用程序的時候。 – davidism