2013-06-19 14 views
10

Sto utilizzando Alembic per gestire le migrazioni per Flask. alembic revision --autogenerate dovrebbe, in teoria, generare automaticamente una migrazione in base alle modifiche nel mio database. Tuttavia, Alembic sta semplicemente generando una migrazione vuota con il comando precedente.Autogenerazione alambicco Migrazioni di Flask-SQLAlchemy vuote

C'è un question very similar to this one, dove il problema è che i modelli corretti non sono stati importati. Tuttavia, ho importato i modelli dal mio Flask app, come mostrato nella 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) 
... 

Così come metadati db importata in env.py ('start' è il nome del file principale mia Flask di app):

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

Esecuzione alembic revision --autogenerate -m "initial_rev" poi genera una migrazione vuota, anche se il mio Flask applicazione sarebbe permetto di dissentire:

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

Modifica

Here is a gist che mostra la struttura del file per la mia app, nonché un po 'di codice aggiuntivo. Sembra che il problema sia che ad Alembic non piace avere il db importato da database.py senza essere inizializzato per primo in __init__.py. Tuttavia, questo non è possibile quando si utilizzano i modelli (a causa delle importazioni cicliche), spiegato in questa risposta SO: https://stackoverflow.com/a/9695045/353878.

Quindi la domanda è, come può essere usato quando Alambicco progetti Flask sono utilizzati come bene?

Modifica # 2

Ho provato anche la stampa db.metadata.sorted_tables, per assicurarsi che i metadati del database è stato importato correttamente. Abbastanza sicuro, l'intero schema del database è stato convogliato al terminale. Quindi, perché Alembic genera funzioni di upgrade/downgrade vuote?

Modifica # 3

ho concluso che la questione ha a che fare con le differenze di db.init_app(app) e db = SQLAlchemy(app), ma io non sono abbastanza sicuro che cosa sta causando il problema. Per verificare questa teoria, ho sostituito from database import db in env.py per essere db = SQLAlchemy(app). Probabilmente una cattiva idea, ma volevo vedere cosa sarebbe successo a scopo di debug.

Alambicco generati automaticamente e riempito l'aggiornamento() e downgrade() metodi- eccezione sono stati invertiti! upgrade() ha abbandonato tutti e tre i miei tavoli, mentre downgrade() li ha creati con tutte le colonne e i metadati corretti. Non ho idea del motivo, ma spero che sia utile per le persone che cercano di capire questo problema.

+0

Come è cambiato lo schema quando è stata eseguita la "revisione alambicco --autogenerate"? – drewman

+0

Ho aggiunto tre tabelle con più colonne. – element119

+0

devi importare i modelli in 'env.py' in modo che si registrino nei metadati. – iElectric

risposta

23

Ecco come uso Alembic con Flask e blueprints.

https://github.com/davidism/basic_flask

Io uso il modello di fabbrica applicazione e chiamare db.init_app all'interno di quella. Dopo lo db = SQLAlchemy() importare tutti i modelli che costituiranno la sottoclasse db.Model in modo che db.metadata ne sia a conoscenza; nota che questo non è fatto nello stabilimento create_app, ma solo in linea durante il modulo init.

Quando si esegue alembic, la cartella del progetto non è inclusa in sys.path quindi l'ho impostata. Quindi creo un'app dalla fabbrica e imposta sqlalchemy.url dalla sua configurazione. Inoltre, importare db e impostare target_metadata = db.metadata.

Questa configurazione funziona per me tutto il tempo, indipendentemente dalla struttura del progetto. Ho incluso un insieme molto semplice di modelli utente e una visione molto stupida in un sotto pacchetto con un progetto. Assicurati di caricare i modelli relavent in load_models, importa le viste dopo aver definito il modello e importa i progetti in init_views.

+0

Grazie mille per la risposta! Ho provato a fare le modifiche che hai suggerito, ma ho due domande: quando viene chiamato init_views()? Inoltre, con questa configurazione, come hai ancora i metodi di appwide (ad es. @ App.before_request)? – element119

+0

@autibyte 'init_views' è chiamato in' create_app'. Simile a 'init_views' puoi creare un' init_helpers' per registrarli quando viene creata l'app. – davidism

Problemi correlati