2010-11-12 8 views
39

Sto programmando un'applicazione web usando sqlalchemy. Tutto è andato liscio durante la prima fase di sviluppo quando il sito non era in produzione. Potrei facilmente cambiare lo schema del database semplicemente cancellando il vecchio database sqlite e crearne uno nuovo da zero.Come gestire in modo efficiente le frequenti modifiche dello schema utilizzando sqlalchemy?

Ora il sito è in produzione e devo conservare i dati, ma voglio comunque mantenere la velocità di sviluppo originale convertendo facilmente il database nel nuovo schema.

Quindi supponiamo di avere model.py alla revisione 50 e model.py una revisione 75, che descrive lo schema del database. Tra questi due schemi la maggior parte delle modifiche è banale, ad esempio una nuova colonna è dichiarata con un valore predefinito e voglio solo aggiungere questo valore predefinito ai vecchi record.

Eventualmente alcune modifiche potrebbero non essere banali e richiedere un pre-calcolo.

Come si gestiscono (o sarebbero) le applicazioni Web in rapida evoluzione con, ad esempio, una o due nuove versioni del codice di produzione al giorno?

A proposito, il sito è scritto su piloni se questo fa alcuna differenza.

+1

"Così è vale la pena usare la migrazione? " dovrebbe essere una domanda separata Hai una risposta su come migrare. Chiedendo i casi d'uso per sqlalchemy-migrate e il tuo caso d'uso specifico è più specifico di questa domanda generale. –

+1

OK, quindi ho bisogno di fare un'altra domanda sulla migrazione per sapere quale risposta accettare. – ascobol

+1

@ascobol: "un'altra domanda sulla migrazione per sapere quale risposta accettare". Falso. Hai delle risposte qui. "Lo strumento [X] ne vale la pena?" non è correlato a "come posso migrare?". Hai delle risposte a "come?". Chiedendo il valore di un particolare strumento non è correlato a "come?" –

risposta

33

Alembic è un nuovo strumento di migrazione del database, scritto dall'autore di SQLAlchemy. Ho trovato molto più facile da usare rispetto alla migrazione di sqlalchemy. Funziona anche perfettamente con Flask-SQLAlchemy.

Auto generare lo script di migrazione dello schema dai vostri modelli SQLAlchemy:

alembic revision --autogenerate -m "description of changes" 

quindi applicare le nuove modifiche dello schema al database:

alembic upgrade head 

Maggiori informazioni qui: http://readthedocs.org/docs/alembic/

+0

Sono d'accordo ma è un po 'difficile farlo funzionare con la tua app. Penso che il nuovo codice 'flask-alembic' sia quello che devo testare. Controlla questo problema: http://stackoverflow.com/questions/14682466/relative-importing-python-module-from-a-subfolder-from-a-different-subfolder#comment20531813_14682466 – Dexter

+2

Dopo aver eseguito "alembic init alembic' e cambiando il mio db username e password in alembic.ini, ho cambiato il mio alembic/env.py in questo: https://gist.github.com/alanhamlett/4721073 Questo era tutto ciò che era necessario per far funzionare l'alambicco con la mia app flask . Spero che sia d'aiuto. –

+0

il mio problema è che non riesco a fare la riga 10 nel tuo codice gist. Non riesco a importare i miei modelli o la mia variabile "db". Non me lo lascerà fare in env.py. – Dexter

12

Cosa facciamo.

  1. Utilizzare l'identificazione "major version". "Versione minore" delle applicazioni. La versione principale è il numero di versione dello schema. Il numero maggiore non è un tipo casuale di "abbastanza nuova funzionalità". È una dichiarazione formale di compatibilità con lo schema del database.

    rilascio 2.3 e 2.4 sia in versione uso dello schema 2.

    Release 3.1 utilizza lo schema versione 3.

  2. Rende la versione dello schema molto, molto visibile. Per SQLite, questo significa mantenere il numero di versione dello schema nel nome del file del database. Per MySQL, usa il nome del database.

  3. Scrittura degli script di migrazione. 2to3.py, 3to4.py. Questi script funzionano in due fasi. (1) Interrogare i vecchi dati nella nuova struttura creando semplici file CSV o JSON. (2) Carica la nuova struttura dai semplici file CSV o JSON senza ulteriori elaborazioni. Questi file di estrazione - perché sono nella struttura corretta, sono veloci da caricare e possono essere facilmente usati come dispositivi di test unitario. Inoltre, non hai mai due database aperti contemporaneamente. Questo rende gli script leggermente più semplici. Infine, i file di caricamento possono essere utilizzati per spostare i dati su un altro server di database.

È molto, molto difficile "automatizzare" la migrazione dello schema. È facile (e comune) avere una chirurgia di database così profonda che uno script automatizzato non possa facilmente mappare i dati dal vecchio schema al nuovo schema.

+0

Come si definisce una modifica dello schema principale? L'aggiunta di una tabella/nuovo modello è considerata una modifica importante dello schema anche se la compatibilità non cambia? Sei un rivale di Firefox nei numeri di versione? (scherzo) – Dexter

12

Utilizzare sqlalchemy-migrate.

È progettato per supportare un approccio agile alla progettazione del database e semplificare la sincronizzazione dei database di sviluppo e produzione, in quanto sono necessarie modifiche dello schema. Rende facile il controllo delle versioni dello schema.

Consideralo come un controllo di versione per lo schema del database. Ad ogni modifica dello schema viene commesso, e sarà in grado di andare avanti/indietro sulle versioni dello schema. In questo modo è possibile aggiornare un client e saprà esattamente quale serie di modifiche applicare sul database del client.

Fa ciò che S.Lott propone nella sua risposta, automaticamente per voi. Rende facile una cosa difficile.

0

Il modo migliore per gestire il problema è riflettere lo schema anziché farlo dichiaratamente. Ho scritto un articolo sull'approccio riflessivo qui: http://petrushev.wordpress.com/2010/06/16/reflective-approach-on-sqlalchemy-usage/ ma ci sono anche altre risorse a riguardo. In questo modo, ogni volta che apporti modifiche allo schema, tutto ciò che devi fare è riavviare l'app e il reflection recupererà i nuovi metadati per le modifiche nelle tabelle. Questo è abbastanza veloce e sqlalchemy lo fa solo una volta per processo. Certo, dovrai gestire i cambiamenti delle relazioni che fai tu stesso.

+5

Giusto per commentare, questa è una pratica orribile nel mondo reale. Mi obbliga a controllare il database rispetto al codice per tutti i tipi di impostazioni come le lunghezze consentite sulle stringhe, ecc. Non ottengo alcun completamento automatico o controllo dell'origine dal mio IDE. Scorro davvero le persone dal fare riflessioni su qualsiasi progetto. È solo un casino con cui lavorare. – Rick

+2

"tutti i tipi di impostazioni come le lunghezze consentite sulle stringhe" - puoi approfondire questo? Che tipo di impostazioni? E, solo perché non si ottiene alcun completamento automatico in ide non significa che l'approccio sia sbagliato. Dopotutto, abbiamo a che fare con python - non con java/C++. – vonPetrushev

+0

Inoltre, ho app 'nel mondo reale' che funzionano con db reflection. Con ER complessi. Non è così complicato per me. – vonPetrushev

Problemi correlati