2013-06-19 12 views
10

Flask için geçişleri işlemek için Alembic kullanıyorum. alembic revision --autogenerate, teoride, veritabanımdaki değişikliklere dayanan bir geçişi otomatikleştirmelidir. Bununla birlikte, Alembic basitçe yukarıdaki komutla boş bir göç yaratıyor.Alembic autogenerates boş Flask-SQLAlchemy geçişleri

question very similar to this one numaralı belgede, sorun doğru modellerin içe aktarılmadığıydu. env.py gösterildiği gibi Ancak, benim Matara uygulamasından modellerini ithal var:

:

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

yanı sıra env.py ithal db meta verileri ('start' benim Matara Uygulamanın ana dosyanın adıdır)

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

Edit

0: my Matara uygulaması aynı fikirde olsa da alembic revision --autogenerate -m "initial_rev" Running
... 
from start import db 
target_metadata = db.metadata 
... 

sonra, boş bir göç üretir

Here is a gist, uygulamanızın dosya yapısını ve bazı ek kodları gösterir. Sorun şu ki, Alembic, __init__.py numaralı telefondan ilk kez başlatılmadan database.py'dan alınan db'ye sahip olmayı sevmiyor. Bununla birlikte, bu SO cevabında açıklanan (döngüsel içe aktarma nedeniyle) planları kullanıldığında bu mümkün değildir: https://stackoverflow.com/a/9695045/353878.

Soru şu ki, Flask planları kullanıldığında Alembic nasıl kullanılabilir?

ben bile emin veritabanı meta doğru ithal ediliyordu yapmak, db.metadata.sorted_tables baskı çalıştı 2

Düzenleme #. Tabii ki, tüm veritabanı şeması terminale bağlandı. Peki neden Alembic boş yükseltme/indirme işlevlerini üretiyor?

Düzenleme 3.

Sorunun db.init_app(app) ve db = SQLAlchemy(app) farklılıklarını bir ilgisi vardır sonucuna oldum ama soruna neden ne olduğundan emin değilim. Bu teoriyi test etmek için db = SQLAlchemy(app) olmak üzere from database import db'u env.py olarak değiştirdim. Muhtemelen kötü bir fikir, ama hata ayıklama amaçları için neler olacağını görmek istedim.

Alembic otomatik olarak yükseltilir ve tersine çevrildiklerinde yükseltme() ve downgrade() yöntemleri doldurulur! upgrade(), tablolarımın her üçünü de düşürürken, downgrade() bunları tüm uygun sütunlar ve meta verilerle oluşturdu. Bunun neden olduğu hakkında hiçbir fikrim yok ama umarım bu problemi çözmeye çalışan insanlar için faydalıdır.

+0

Şemanınız "alembic revision --autogenerate" çalıştırdığınızda nasıl değişti? – drewman

+0

Birkaç sütunlu üç tablo ekledim. – element119

+0

, "env.py" 'de model almanız ve böylece meta verilere kaydolmanız gerekir. – iElectric

cevap

23

Alembic'i Flask ve taslaklarıyla nasıl kullanıyorum.

https://github.com/davidism/basic_flask

Başvuru fabrika deseni kullanmak ve bu dahilinde db.init_app diyoruz. db = SQLAlchemy()'dan sonra db.Model alt sınıfına giren tüm modelleri içe aktarıyorum, böylece db.metadata bunların farkındadır; Not, bu create_app fabrikada değil, yalnızca modülün init sırasında satır içi yapılır.

alembic çalıştırıldığında, proje klasörü sys.path'a dahil edilmediğinden, bunu ayarlıyorum. Ardından fabrikadan bir uygulama oluşturup, yapılandırmasından sqlalchemy.url'u ayarlıyorum. Ayrıca, db'u içe aktarıyorum ve target_metadata = db.metadata'u ayarlıyorum.

Bu kurulum, proje yapısı ne olursa olsun her zaman benim için çalışır. Çok basit bir kullanıcı modelleri seti ve bir planın bir alt paketinde çok aptalca bir görünüme yer verdim. Yalnızca yeniden adlandırılan modelleri load_models'a yüklediğinizden emin olun, blueprint'i tanımladıktan sonra görünümleri içe aktarın ve planları init_views'a aktarın.

+0

Cevabınız için çok teşekkürler! Önerdiğiniz değişiklikleri yapmayı denedim, ancak iki sorum var: init_views() ne zaman çağrılıyor? Ayrıca, bu kurulumla, hâlâ uygulama yöntemlerini nasıl kullanıyorsunuz (ör. @ App.before_request)? – element119

+0

@autibyte 'init_views',' create_app' olarak adlandırılır. "Init_views" öğesine benzer şekilde, uygulama oluşturulduğunda bunları kaydetmek için bir "init_helpers" oluşturabilirsiniz. – davidism