Strategia per la versione che controlla le modifiche al database durante lo sviluppo

1

Sto riprogettando uno strumento CRM, di sorta, da zero. Stiamo creando l'applicazione e il database da zero. Affinché gli sviluppatori rimangano lontani gli uni dagli altri, ogni sviluppatore ha una copia locale del database dell'applicazione piuttosto che condividere un singolo database di sviluppo. Ciò evita il caso in cui lo sviluppatore 1 effettui una modifica al database che funzioni per loro, ma interrompe l'applicazione per tutti gli altri finché lo sviluppatore 1 non verifica le loro modifiche al codice.

Su suggerimento di una risposta a una simile domanda simile che ho visto quando stavamo iniziando, manteniamo nel controllo del codice sorgente una cartella di script SQL numerati sequenzialmente. Quando uno sviluppatore apporta modifiche al proprio database, esegue lo script di tutte le modifiche in un file SQL e lo controlla insieme alle modifiche al codice dell'applicazione. In teoria, suona bene, ma qui ci sono alcune difficoltà:

  1. Se 5.sql è l'ultimo script di modifica del database archiviato, tutti gli sviluppatori (di solito tutti) che apportano nuove modifiche al database creano un file denominato 6.sql perché si tratta di una situazione di tipo first-come-first-serve. Ma può esserci solo un 6.sql archiviato. Quindi devi controllare quali file stanno pianificando di controllare prima di creare il tuo prossimo file SQL o appena prima di fare il check-in, controllare cosa c'è già e rinominare il tuo file il prossimo (che è tecnicamente ancora soggetto a un conflitto se due sviluppatori effettuano il check-in contemporaneamente).
  2. Una volta aggiornato, è necessario eseguire gli ultimi file SQL per aggiornare il database con l'ultimo codice recuperato. Questo è facile da dimenticare fino a quando non si esegue l'applicazione e si fa esplodere qualcosa. Ma il problema più grande è che è difficile ricordare quale file è stato eseguito per ultimo, cioè su quale versione il tuo database è già acceso.
  3. Nessuna fusione o rilevamento di conflitti. Se 2 sviluppatori stanno controllando gli script di aggiornamento nello stesso momento, gli script di sviluppatore 2 potrebbero avere modifiche in conflitto con le nuove modifiche degli sviluppatori 1. PER ESEMPIO. Supponiamo che lo sviluppatore 2 scriva uno script per modificare la colonna Person.ModifiedDate su NOT NULL, ma appena prima che lo sviluppatore 2 effettui il check in, lo sviluppatore 1 controlla uno script che modifica il nome di Person.ModifiedDate in Person.LastModifiedDate. Lo sviluppatore 2 rinominerà il proprio file in modo che il nome del file non sia in conflitto e verifichi inconsapevolmente quello che ora è uno script rotto, o dovrà seguire un protocollo che non può controllare uno script sql fino a quando non applica tutti gli ultimi e convalida il loro script. Questo è un processo doloroso, specialmente se lo sviluppatore 2 è andato e ha applicato le modifiche dello sviluppatore 1, aggiornato i propri script e poi ha provato a fare il check-in solo per trovare lo sviluppatore 3 ha ora controllato uno script.

Quindi sto pensando di scrivere un'app console che viene eseguita prima della compilazione per afferrare i file di script ed eseguirli contro il database in ordine. Dovrebbe solo memorizzare l'ultimo file che ha eseguito da qualche parte in modo da sapere se ci sono nuovi script da eseguire la volta successiva. Sembra che sistemerà il n. 2, ma qualcuno usa una strategia migliore che risolva tutti i problemi? Finora abbiamo evitato i conflitti lavorando su parti non correlate dell'applicazione, ma man mano che andiamo avanti diventeremo sempre più difficili da fare e la strategia attuale richiede troppa disciplina per gli sviluppatori - sappiate che finirà per causare problemi.

    
posta xr280xr 26.09.2017 - 20:50
fonte

2 risposte

4

Queste sono chiamate migrazioni di database. Sei sulla strada giusta. Lasciami rispondere ai tuoi problemi.

  1. or just before you check in, check what is already there and rename your file to the next one (which is still technically subject to a conflict if two developers are checking in at the same time)

La prima persona che spinge al tuo ramo di integrazione vince e tutti gli altri devono rinominare. Non dovrebbe essere un grosso problema, e dovresti assicurarti che sia semplice come rinominare un file - non dovresti dover riconfigurare anche altre cose. Non penso che dovresti cercare di evitarlo perché l'alternativa sta cercando di prevedere quale sviluppatore finirà per primo, il che inevitabilmente causerà dei colli di bottiglia.

  1. When you get latest you have to go run the latest SQL files to bring your database up to date with the latest code you retrieved. This is easy to forget until you run the application and have something blow up. But the bigger problem is it's hard to remember which file you ran last - i.e. which version your database is already on.

Questo è il vantaggio di avere uno strumento che esegue le migrazioni del database per te. Esistono due strumenti di migrazione molto popolari: Flyway e Liquibase . Questi strumenti tengono traccia di quali migrazioni sono state eseguite e devi configurarle per l'esecuzione all'avvio dell'app. Lo strumento esegue la scansione della directory per tutti gli script che non ha ancora visto e li applica al database uno per uno. È praticamente ciò che stai proponendo di fare da solo, ma è già scritto e maturo.

  1. No merging or conflict detection. If 2 developers are checking in update scripts at the same time, developer 2's scripts could have conflicting changes with developer 1s new changes.

Lo strumento ti aiuterà anche qui. I test di integrazione devono eseguire migrazioni su un database pulito e, se sono presenti due migrazioni con lo stesso numero di versione, lo strumento genera un errore. Quindi, la prima persona a spingere un numero di versione dovrebbe superare i test e se un'altra persona ha lo stesso numero di versione, i test inizieranno senza esito.

    
risposta data 27.09.2017 - 02:25
fonte
1

L'articolo fornito da Robert Harvey ha la risposta per le tue tre preoccupazioni. Il punto chiave qui è che hai bisogno di un elemento di configurazione per eseguire gli script di migrazione del database. Gli script di migrazione del database e il codice dell'applicazione sono nello stesso repository ed eseguiti da CI (Continuous Integration) insieme.

Eventuali conflitti semantici che hai menzionato al punto 3 dovrebbero essere rilevati da errori degli script di aggiornamento del database o dal fallimento di test automatici. Stai pensando di creare un'app per console. Generalmente, non è necessario. In effetti, lo script di build in esecuzione in CI dovrebbe servire a questo scopo. Solo le cose che ti servono assicurano che lo script di build in CI possa essere eseguito in locale a livello locale e incoraggia gli sviluppatori a eseguire script di build prima del check-in .

Un'altra preoccupazione che hai è potenziale più conflitti di tempo (più sviluppatori). La risposta qui potrebbe essere fuori tema. Tuttavia, penso che sia degno di nota. Prova a separare i tuoi sistemi in diversi contesti limitati e creare database all'interno del contesto. L'integrazione nel database condiviso è l'inizio del caos.

    
risposta data 27.09.2017 - 06:35
fonte

Leggi altre domande sui tag