E se ci sono troppe migrations?

22 views
Skip to first unread message

Simone Gentili

unread,
Jun 15, 2013, 3:58:47 AM6/15/13
to symfo...@googlegroups.com
C
​iao di nuovo,

modificato spesso le entità di un progetto, mi capita di avere diversi files per le migrations. Il problema viene quando lancio i test per i quali voglio essere certo di avere un db pulito. Ecco perché eseguo questi tre comandi (all'interno di uno script).

./app/console doctrine:database:drop --force
./app/console doctrine:database:create
./app/console doctrine:migrations:migrate --no-interaction

​​
​Il problema nasce quando i files delle migrations iniziano a crescere. Tanti files == tanto tempo per eseguire le migrations. Così ho pensato di affrontare il problema complicando un po' le cose:​

rm -rf app/DoctrineMigrations
./app/console doctrine:database:drop --force
./app/console doctrine:database:create
./app/console doctrine:migrations:diff
./app/console doctrine:migrations:migrate --no-interaction

​Ogni volta che lancio i test, faccio in modo che le migrations vengano "compresse" in un solo file. Queste rende più veloce la migrazione. Ovviamente la cosa non funziona se l'applicazione è in produzione. In quel caso pensavo di fare un bundle in grado di eseguire questi comandi e di comprimere le migrations dall'ultimo deploy fino a questo momento. In questo modo, ogni deploy avrebbe le proprie migration.

Per essere si tratta di piccoli passaggi che si possono fare tranquillamente a mano. Voi avete mai affrontato questo tipo di problematica?
Ha senso se si fa deploy automatico?
Idee?
Dubbi?
Considerazioni?
​La pensate anche voi come chi ogni tanto mi dice "Fatti meno problemi" XD.​

Simone Gentili

unread,
Jun 15, 2013, 4:16:29 AM6/15/13
to symfo...@googlegroups.com
Ho già trovato un "problema". Se lancio

rm -rf app/DoctrineMigrations

e

./app/console doctrine:migrations:diff

ogni volta che lancio dei test ottengo la cancellazione delle vecchie migrations e la creazione di una nuova. Penso che farò uno script indipendente che pulisce le migrations. E magari, dopo il deploy, potrei pensare ad una soluzione che mergi le migrazioni dall'ultimo deploy sino a questo momento.

Giorgio Cefaro

unread,
Jun 15, 2013, 4:36:17 AM6/15/13
to symfo...@googlegroups.com

Non capisco l'utilità di piallare ad ogni giro test il db. C'è forse  del codice che altera lo schema? E' sufficiente lo svuotamento delle tabelle, no? Ma soprattutto le migrations imho devono rimanere scolpite nella roccia, attaccate coi denti ad ogni committata per garantire la possibilità di poter tornare indietro con sicurezza!

Simone Gentili

unread,
Jun 15, 2013, 5:05:43 AM6/15/13
to symfo...@googlegroups.com
Testo tutto con Behat. In pratica non scrivo quasi nessun test funzionale e quasi nessun test unitario. Ogni feature viene eseguita in sequenza e c'è quindi "memoria" degli scenari precedenti. A questo punto voglio essere certo di conoscere l'id dei record appena creati. Ogni volta che testo la mia applicazione, la testo come se l'avessi appena installata in questa macchina. In questo modo sono certo che i test lanciati qui, o in un'altra macchina, si comportano allo stesso modo.

A dire il vero piallo e ricreo il db ogni volta perché mi sembra il metodo più veloce di svuotare tutte le tabelle al volo. Ma tu mi fai intuire che non lo fai. Vuoi dire che quando lanci i test non rilanci le migrations?


Il giorno 15 giugno 2013 10:36, Giorgio Cefaro <giorgio...@gmail.com> ha scritto:

Non capisco l'utilità di piallare ad ogni giro test il db. C'è forse  del codice che altera lo schema? E' sufficiente lo svuotamento delle tabelle, no? Ma soprattutto le migrations imho devono rimanere scolpite nella roccia, attaccate coi denti ad ogni committata per garantire la possibilità di poter tornare indietro con sicurezza!

--
Hai ricevuto questo messaggio perché sei iscritto al gruppo "symfony-it" di Google Gruppi.
Visita questo gruppo all'indirizzo http://groups.google.com/group/symfony-it.
 
 

Andrea Giuliano

unread,
Jun 15, 2013, 5:29:56 AM6/15/13
to symfo...@googlegroups.com
Ciao Simone, 
io non capisco perchè ogni volta fai le migrations.
Le migrazioni servono *solo* in produzione. Se stai in dev/locale e lanci un create/update, il database viene creato/aggiornato all'ultima versione del db che hai.
Quindi, se non ho capito male ciò che fai, credo sia un passaggio che puoi evitarti.
Per il fatto che non hai test unitari/funzionali, Behat non è un insieme che include unitari e funzionali, quindi ti consiglio di testare anche il codice.
Quindi va da sé, che con i test unitari, non hai bisogno del db; con i test di integrazione e funzionali, puoi utilizzare delle fixtures e ripristinare il database per ogni test (e questo è reso facile con DoctrineFixturesBundle) così da fare in modo che hai una situazione nota a livello di db e scolleghi la dipendenza dei test (sempre db-parlando).



--
Andrea Giuliano

Simone Gentili

unread,
Jun 15, 2013, 6:19:07 AM6/15/13
to symfo...@googlegroups.com
Andrea, tu come ti comporti se hai usato una update ed hai del codice da committare? Committi il codice senza migration?

Non è che non ho test unitari o funzionali. E' che non servono per testare quello che sto testando.

Andrea Giuliano

unread,
Jun 15, 2013, 6:23:30 AM6/15/13
to symfo...@googlegroups.com
In linea del tutto generale, quando fai una migration significa che probabilmente hai nuove esigenze db-side.
Quindi diciamo che la tua applicazione è in uno stato consistente al tempo t.
Al tempo t+1 inserisci le migrations (perchè probabilmente ti serviranno per fare la tua feature), e magari inserisci anche un po di codice che utilizza il nuovo db.
Io, se mi trovassi in questa situazione committerei le migrations al tempo t+1 (senza il codice che le utilizza) poi chiuderei la feature al tempo t+2 e committerei quella. 
Così tutti i tuoi commit sono stabili e ad-sense.

--
Andrea Giuliano

Simone Gentili

unread,
Jun 15, 2013, 6:29:57 AM6/15/13
to symfo...@googlegroups.com
Quello che mi sfugge è, ... come inserisci le migrations se hai lanciato la update? 

Andrea Giuliano

unread,
Jun 15, 2013, 6:33:21 AM6/15/13
to symfo...@googlegroups.com
Scusa ma tu come generi le migrations?
La migration è semplicemente una o più query che vengono lanciate per passare il db da una versione ad un'altra.
Il fatto è che comunque il tuo schema (le tue entities) devono essere sempre aggiornate all'ultima versione. Di conseguenza, doctrine:update sarà sufficiente, perchè leggerà le proprietà delle entità da creare dal tuo schema di entities.
Se non aggiorni le Entities, come fai con i getter/setter e gli altri metodi per l'oggetto?
--
Andrea Giuliano

Simone Gentili

unread,
Jun 15, 2013, 7:38:25 AM6/15/13
to symfo...@googlegroups.com
​Sono arrivato a questa conclusione: mi sono sempre comportato come se dovessi poter deployare ad ogni commit che faccio. Dunque non era sbagliata l'idea di lanciare sempre le migrations ma era proprio sbagliato comportarsi come se dovessi deployare ad ogni commit, ... e sulla mia macchina. In pratica il mio utilizzo delle migrations era decisamente ... "fantasioso".

​Penso cambierò il mio approccio, creando ed usando le migrations solo in fase di deploy.

Dunque ringrazio immensamente anche Andrea Giuliano che ha avuto la pazienza di mostrarmi la via.

leonardo proietti

unread,
Jun 15, 2013, 7:44:18 AM6/15/13
to symfo...@googlegroups.com
>mi sono sempre comportato come se dovessi poter deployare ad ogni commit che faccio. Dunque non era sbagliata l'idea di lanciare sempre le migrations

si ma non è che ad ogni deploy sbraghi il db e poi rilanci le migrazioni,
il cui scopo principale è proprio quello di aggiornare a caldo il database :-)

Andrea Giuliano

unread,
Jun 15, 2013, 7:47:24 AM6/15/13
to symfo...@googlegroups.com
> si ma non è che ad ogni deploy sbraghi il db e poi rilanci le migrazioni,
> il cui scopo principale è proprio quello di aggiornare a caldo il database :-)

Esatto, era proprio questo il kernel della discussione.
In pratica, spiegavo a Simone che è inutile lanciare le migrazioni in locale, essendo lo schema già aggiornato un doctrine:schema:update è più che sufficiente.
Poi parlavamo anche del numero elevato delle migrations, che sono un campanellino d'allarme che qualcosa non va, come ha scritto Simone stesso nel post precedente :)

Simone Gentili

unread,
Jun 15, 2013, 7:56:18 AM6/15/13
to symfo...@googlegroups.com
La dico in un altro modo: stavo risolvendo il problema delle migrations nel posto sbagliato.

Avrei dovuto accorgermene mentre pensavo "committo anche la migrations COME SE dovessi deployare in un qualsiasi momento". Aggiungevo ad ogni commit lo sforzo della migrations. Inutile, visto che serve solo QUANDO devo deployare.



Giorgio Cefaro

unread,
Jun 15, 2013, 8:00:50 AM6/15/13
to symfo...@googlegroups.com


>è inutile lanciare le migrazioni in locale, essendo lo schema già
>aggiornato un doctrine:schema:update è più che sufficiente

Io su questo mi sentirei di essere più cauto: i test li farei girare cmq in un database costruito attraverso tutte le migrazioni, anche confidando nel fatto che il doctrine:update porta allo stesso risultato: posso così testare atomicamente senza margini di incertezza tutti gli stati intermedi del db.

leonardo proietti

unread,
Jun 15, 2013, 8:01:24 AM6/15/13
to symfo...@googlegroups.com
>stavo risolvendo il problema delle migrations nel posto sbagliato

ma scusa, che problema?
se ti serve cambiare la struttura del db fai una migrazione e se hai una nuova migrazione la pushi.

Andrea Giuliano

unread,
Jun 15, 2013, 8:05:30 AM6/15/13
to symfo...@googlegroups.com
Io su questo mi sentirei di essere più cauto: i test li farei girare cmq in un database costruito attraverso tutte le migrazioni, anche confidando nel fatto che il doctrine:update porta allo stesso risultato: posso così testare atomicamente senza margini di incertezza tutti gli stati intermedi del db.

Si, ovviamente i test su un db costruito dalle migrazioni è indicato. Anche se una migrazione non dovrebbe essere corposa, nel senso che se una migrazione altera una percentuale alta del db, c'è stato comunque qualche problema di fondo. 

Simone Gentili

unread,
Jun 15, 2013, 8:19:01 AM6/15/13
to symfo...@googlegroups.com
Il problema è che io creavo e pushavo tante migrations, ma quando c'era da fare il deploy me le sistemavo a mano. Lo stesso risultato si può ottenere creando le migrations solo in fase di deploy.


--

leonardo proietti

unread,
Jun 15, 2013, 8:38:44 AM6/15/13
to symfo...@googlegroups.com
>Il problema è che io creavo e pushavo tante migrations, ma quando c'era da fare il deploy me le sistemavo a mano

ecco si, questo è un problema.
personalmente: migro, testo, rilascio.

poi ci sono casi eccezionali in cui si possono usare le migrazioni 
per setuppare dei dati che servono all'applicazione, ma è un modo che non mi convince.

Ciao
Leonardo 

eux

unread,
Jun 17, 2013, 3:56:22 AM6/17/13
to symfo...@googlegroups.com, leonardo...@gmail.com
ciao Simone,


> Ogni feature viene eseguita in sequenza e c'è quindi "memoria" degli scenari precedenti. A questo punto voglio essere
> certo di conoscere l'id dei record appena creati.

questa frase mi fa sospettare che oltre a quanto hanno detto gli altri ci sono un paio di problemi pratici nella scrittura dei test.

Non dovresti mai fare affidamento sulle ID dei record. Dovresti fare delle query significative sui campi per controllare o tirare fuori i record che ti servono. In questo modo per riportare il database ad uno stato di riutilizzabilità puoi ricaricare solo le fixtures.

Inoltre un test deve sempre lasciare il sistema nello stato in cui lo ha trovato. Puoi usare gli hook di behat per far sì che alla fine del test il sistema venga ripristinato.

Simone Gentili

unread,
Jun 17, 2013, 4:43:07 AM6/17/13
to symfo...@googlegroups.com, leonardo proietti

Il giorno 17 giugno 2013 09:56, eux <eux...@gmail.com> ha scritto:
questa frase mi fa sospettare che oltre a quanto hanno detto gli altri ci sono un paio di problemi pratici nella scrittura dei test.

Oddio, io faccio si che una feature abbia tutta una sua storia. Quindi faccio affidamento all'ordine degli scenari che scrivo. Potrei anche fare a meno degli id (che avrebbe molto senso). In ambito "Behat", e riguardo al fatto di lasciare il sistema nello stato ​in cui lo si trova ...

Tu con test intendi "ciascun scenario"?

Se la risposta è si siamo allo stesso punto di prima: sto proprio lavorando male.

Reply all
Reply to author
Forward
0 new messages