{"id":70973,"date":"2020-02-23T00:58:26","date_gmt":"2020-02-22T21:58:26","guid":{"rendered":"https:\/\/prohoster.info\/blog\/kak-ne-vystrelit-sebe-v-nogu-ispolzuya-liquibase"},"modified":"2020-03-03T16:14:41","modified_gmt":"2020-03-03T13:14:41","slug":"kak-ne-vystrelit-sebe-v-nogu-ispolzuya-liquibase","status":"publish","type":"post","link":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/kak-ne-vystrelit-sebe-v-nogu-ispolzuya-liquibase","title":{"rendered":"Come non spararsi sui piedi usando Liquibase","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Non \u00e8 mai successo, eppure succede di nuovo!<\/p>\n<p><\/p>\n<p>In un nuovo progetto abbiamo deciso di utilizzare Liquibase sin dall'inizio per evitare problemi in futuro. Come si \u00e8 rivelato, non tutti i membri pi\u00f9 giovani del team sanno usarlo correttamente. Ho condotto un workshop interno che ho poi deciso di trasformare in un articolo. <\/p>\n<p><\/p>\n<p>L'articolo include consigli utili e una descrizione delle tre trappole pi\u00f9 comuni in cui si pu\u00f2 incappare lavorando con strumenti di migrazione per database relazionali, in particolare Liquibase. \u00c8 destinato a sviluppatori Java di livello Junior e Middle; per sviluppatori pi\u00f9 esperti potrebbe risultare interessante per strutturare e rinfrescare ci\u00f2 che probabilmente conoscono gi\u00e0. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come non spararsi sui piedi usando Liquibase\" src=\"\/wp-content\/uploads\/2020\/02\/f8b3c9a456bde7aa123702fae132b4b8.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Liquibase e Flyway sono le principali tecnologie in concorrenza per la gestione delle versioni delle strutture relazionali nel mondo Java. La prima \u00e8 completamente gratuita e nella pratica viene scelta pi\u00f9 frequentemente, quindi Liquibase \u00e8 stata scelta come protagonista della pubblicazione. Tuttavia, alcune delle pratiche descritte potrebbero essere universali, a seconda dell'architettura della tua applicazione. <\/p>\n<p><\/p>\n<p>Le migrazioni delle strutture relazionali sono emerse come un modo necessario per affrontare la scarsa flessibilit\u00e0 degli archivi di dati relazionali. Nell'era della programmazione orientata agli oggetti, il lavoro con i database implicava che una volta descritta una schema, non fosse pi\u00f9 necessario modificarlo. Tuttavia, la realt\u00e0 \u00e8 che tutto cambia nel tempo, e le modifiche nella struttura delle tabelle sono necessarie piuttosto frequentemente. \u00c8 naturale che questo processo possa essere doloroso e sgradevole. <\/p>\n<p><\/p>\n<p>Non entrer\u00f2 nei dettagli della tecnologia e nelle istruzioni per aggiungere la libreria al proprio progetto, su questo tema sono stati scritti sufficienti articoli:<\/p>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/460377\/\">Utilizzare Liquibase per gestire la struttura del database in un'applicazione Spring Boot. Parte 1<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/460907\/\">Utilizzare Liquibase per gestire la struttura del database in un'applicazione Spring Boot. Parte 2<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/436994\/\">Liquibase e Maven<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/330662\/\">Approcci alla versioning delle modifiche del database<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/271719\/\">Spring MVC\/Security, REST, Hibernate, Liquibase avviati in due righe<\/a><\/noindex><\/li>\n<\/ul>\n<p><\/p>\n<p>Inoltre, c'era gi\u00e0 un ottimo articolo sui consigli utili:<\/p>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/179425\/\">Utilizzare Liquibase senza stress. 10 consigli dall'esperienza reale di sviluppo<\/a><\/noindex><\/li>\n<\/ul>\n<p><\/p>\n<h2 id=\"sovety\">Consigli<\/h2>\n<p><\/p>\n<p>Desidero condividere i miei consigli e commenti, nati attraverso il sudore, il sangue e il dolore nella risoluzione dei problemi di migrazione.<\/p>\n<p><\/p>\n<h3 id=\"1--pered-rabotoy-sleduet-oznakomitsya-s-razdelom-luchshih-praktik-na-saytehttpswwwliquibaseorgbestpracticeshtml-liquibase\">1. Prima di iniziare, \u00e8 consigliabile familiarizzare con la sezione delle migliori pratiche su <noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/bestpractices.html\">sito<\/a><\/noindex> Liquibase<\/h3>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/bestpractices.html\">Qui<\/a><\/noindex> vengono descritti aspetti semplici ma fondamentali, senza i quali l'uso della libreria pu\u00f2 complicarti la vita. Ad esempio, un approccio non strutturato nella gestione dei changelog porter\u00e0 inevitabilmente a confusione e migrazioni rotte. Se non si applicano cambiamenti strutturali e logici dei servizi contemporaneamente, c'\u00e8 un'alta probabilit\u00e0 che si verifichino test falliti o un ambiente non funzionante. Inoltre, le raccomandazioni per l'uso di Liquibase sul sito ufficiale includono un punto relativo allo sviluppo e alla verifica di script di rollback insieme agli script di migrazione principali. Infine, nell'articolo <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/178665\/\">https:\/\/habr.com\/ru\/post\/178665\/<\/a><\/noindex> troverai esempi di codice relativi alle migrazioni e al meccanismo di rollback. <\/p>\n<p><\/p>\n<h3 id=\"2-esli-nachali-ispolzovat-sredstva-migracii--ne-dopuskayte-manualnyh-ispravleniy-v-strukture-bazy\">2. Se inizi a utilizzare strumenti di migrazione, evita le correzioni manuali nella struttura del database.<\/h3>\n<p><\/p>\n<p>Come si suol dire: \u00abUna volta Persil, sempre Persil\u00bb. Se il database della tua applicazione inizia a essere gestito tramite Liquibase, qualsiasi modifica manuale porta immediatamente a uno stato incoerente, e il livello di fiducia nei changelog scende a zero. I rischi potenziali includono ore spese per ripristinare il database, e nel peggiore dei casi, un server compromesso. Se nella tua squadra c'\u00e8 un DBA Architect 'anziano', spiegagli pazientemente e con attenzione quanto sar\u00e0 disastroso se decide di modificare il database a suo piacimento tramite SQL Developer. <\/p>\n<p><\/p>\n<h3 id=\"3-esli-chendzhset-uzhe-byl-zapushen-v-repozitoriy-izbegayte-redaktirovaniya\">3. Se il changelog \u00e8 gi\u00e0 stato pushato nel repository, evita di effettuare modifiche.<\/h3>\n<p><\/p>\n<p>Se un altro sviluppatore ha fatto un pull e ha applicato un changelist che verr\u00e0 successivamente modificato, sicuramente parler\u00e0 bene di te quando ricever\u00e0 un errore all'avvio dell'applicazione. Se la modifica del changelist in qualche modo penetra nel dev, dovr\u00e0 prendere la strada scivolosa degli hotfix. Il cuore del problema riguarda la validazione delle modifiche tramite hash \u2014 il meccanismo principale di Liquibase. Quando si modifica il codice del changelist, cambia anche l'hash. La modifica dei changelist \u00e8 possibile solo quando c'\u00e8 la possibilit\u00e0 di ripristinare l'intero database da zero senza perdita di dati. In tal caso, il refactoring del codice SQL o XML pu\u00f2, al contrario, semplificare la vita, rendendo le migrazioni pi\u00f9 leggibili. Un esempio potrebbe essere la situazione in cui, all'avvio dell'applicazione, lo schema del database originale \u00e8 stato concordato all'interno del team. <\/p>\n<p><\/p>\n<h3 id=\"4--imey-proverennye-bekapy-baz-dannyh-esli-eto-vozmozhno\">4. Tieni backup verificati dei database, se possibile<\/h3>\n<p><\/p>\n<p>Qui penso sia tutto chiaro. Nel caso in cui la migrazione non andasse a buon fine, tutto pu\u00f2 essere ripristinato. In Liquibase c'\u00e8 uno strumento per il rollback delle modifiche, ma gli script per il rollback vengono scritti dallo stesso sviluppatore e possono presentare problemi con la stessa probabilit\u00e0 degli script del changelog principale. Questo significa che \u00e8 sempre utile essere previdenti con i backup. <\/p>\n<p><\/p>\n<h3 id=\"5-ispolzuy-proverennye-bekapy-baz-dannyh-v-razrabotke-esli-eto-vozmozhno\">5. Utilizza backup di database verificati durante lo sviluppo, se possibile.<\/h3>\n<p><\/p>\n<p>Se questo non contraddice i contratti e la privacy, la base dati non contiene dati personali ed \u00e8 di dimensioni gestibili \u2014 prima di applicare migrazioni su server live, puoi testare come funziona sulla macchina dello sviluppatore e identificare quasi il 100% dei problemi potenziali durante la migrazione. <\/p>\n<p><\/p>\n<h3 id=\"6-obschaysya-s-drugimi-razrabotchikami-v-komande\">6. Comunica con gli altri sviluppatori del team.<\/h3>\n<p><\/p>\n<p>In a well-organized development process, everyone in the team knows what each member is working on. In reality, this is often not the case, so if you are preparing changes to the database structure as part of your task, it's advisable to notify the entire team about it. If someone makes changes in parallel, you should organize yourselves carefully. It's important to communicate with colleagues even after the work is completed, not just at the start. Many potential issues with change sets can be resolved during the code review stage. <\/p>\n<p><\/p>\n<h3 id=\"7-dumay-chto-delaesh\">7. Think about what you are doing!<\/h3>\n<p><\/p>\n<p>It may seem like an obvious piece of advice applicable to any situation. However, many problems could be avoided if the developer took a moment to analyze what they are doing and what impact it might have. Working with migrations always requires additional attention and care. <\/p>\n<p><\/p>\n<h2 id=\"lovushki\">Traps<\/h2>\n<p><\/p>\n<p>Now let's consider typical traps you might fall into if you don't follow the advice above, and what exactly to do?<\/p>\n<p><\/p>\n<h3 id=\"situaciya-1-dva-razrabotchika-pytayutsya-odnovremenno-dobavlyat-novye-chendzhsety\">Situation 1. Two developers are trying to add new change sets simultaneously.<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come non spararsi sui piedi usando Liquibase\" src=\"\/wp-content\/uploads\/2020\/02\/20706fc970510bc06634fa001a4c7ceb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nVasia e Petia vogliono creare un changset della versione 4, senza sapere l'uno dell'altro. Hanno effettuato modifiche nella struttura del database e hanno inviato una pull request, con diversi file del changset. Di seguito viene proposto il seguente meccanismo di azione:<\/p>\n<p><\/p>\n<h4 id=\"kak-reshat\">Come procedere<\/h4>\n<p><\/p>\n<ol>\n<li>In qualche modo, i colleghi devono concordare l'ordine in cui devono essere applicati i loro changset; ad esempio, quello di Petia dovrebbe essere applicato per primo. <\/li>\n<li>Qualcuno deve includere il secondo nel proprio e contrassegnare il changset di Vasia come versione 5. Questo pu\u00f2 essere fatto tramite Cherry Pick o un merge accurato. <\/li>\n<li>Dopo le modifiche, \u00e8 fondamentale verificare la validit\u00e0 delle azioni effettuate.<br \/>\nIn realt\u00e0, i meccanismi di Liquibase consentono di avere nel repository due changset della versione 4, quindi si pu\u00f2 lasciare tutto com'\u00e8. Ovvero, avrete semplicemente due modifiche della versione 4 con nomi diversi. Con questo approccio, in seguito diventa molto difficile orientarsi nelle versioni del database. <\/li>\n<\/ol>\n<p><\/p>\n<p>Inoltre, Liquibase, come la dimora degli hobbit, custodisce molti segreti. Uno di questi \u00e8 la chiave validCheckSum, introdotta con la versione 1.7, che consente di specificare un valore di checksum valido per un determinato changeSet, indipendentemente da ci\u00f2 che \u00e8 memorizzato nel database. La documentazione <noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/documentation\/changeset.html\">https:\/\/www.liquibase.org\/documentation\/changeset.html<\/a><\/noindex> afferma quanto segue:<\/p>\n<p><\/p>\n<blockquote><p>Aggiungi un checksum che sia considerato valido per questo changeSet, indipendentemente da ci\u00f2 che \u00e8 memorizzato nel database. Utilizzato principalmente quando \u00e8 necessario modificare un changeSet e non si desidera che vengano sollevati errori nei database sui quali \u00e8 gi\u00e0 stato eseguito (procedura non raccomandata).<\/p><\/blockquote>\n<p>S\u00ec, questa procedura non \u00e8 consigliata. Ma a volte un potente mago chiaro padroneggia anche tecniche oscure. <\/p>\n<p><\/p>\n<h3 id=\"situaciya-2-migraciya-kotoraya-zavisit-ot-dannyh\">Situazione 2. Migrazione che dipende dai dati.<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Come non spararsi sui piedi usando Liquibase\" src=\"\/wp-content\/uploads\/2020\/02\/31a6eebb55278c0631115bf16483c7b8.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Supponiamo che non sia possibile utilizzare backup dei database dai server in produzione. Petya ha creato un changeSet, lo ha testato localmente e con piena fiducia nella sua correttezza ha fatto una pull request nello sviluppo. Il leader del progetto ha verificato, giusto per essere sicuro, se Petya l'aveva controllato, e poi ha fuso il tutto. Ma il deployment sul server di sviluppo \u00e8 fallito.<\/p>\n<p><\/p>\n<p>In realt\u00e0, \u00e8 possibile, e nessuno \u00e8 immune da ci\u00f2. Questo accade quando le modifiche alla struttura delle tabelle sono in qualche modo legate a dati specifici del database. \u00c8 ovvio che se il database di Piero \u00e8 riempito solo con dati di test, potrebbe non coprire tutti i casi problematici. Ad esempio, quando si elimina una tabella, si scopre che ci sono registrazioni in altre tabelle collegate tramite chiavi esterne (Foreign Key) ai record eliminati. Oppure, quando si modifica il tipo di colonna, emerge che non il 100% dei dati pu\u00f2 essere convertito nel nuovo tipo. <\/p>\n<p><\/p>\n<h4 id=\"kak-reshat-1\">Come procedere<\/h4>\n<p><\/p>\n<ul>\n<li>Scrivere script speciali che verranno applicati una sola volta insieme alla migrazione e porteranno i dati nel formato corretto. Questo \u00e8 un modo generale per risolvere il problema del trasferimento dei dati in nuove strutture gi\u00e0 dopo l'applicazione delle migrazioni, ma qualcosa di simile pu\u00f2 essere applicato anche prima, in casi particolari. Questo approccio, ovviamente, non \u00e8 sempre disponibile, poich\u00e9 modificare i dati su server attivi pu\u00f2 essere pericoloso e persino disastroso. <\/li>\n<li>Un'altra soluzione complessa \u00e8 modificare il changelog esistente. La difficolt\u00e0 consiste nel fatto che tutte le basi dati in cui \u00e8 stato applicato nella sua attuale forma dovranno essere ripristinate. \u00c8 molto probabile che l'intero team backend sar\u00e0 costretto a reinstallare la base dati localmente da zero. <\/li>\n<li>La soluzione pi\u00f9 universale \u00e8 trasferire il problema dei dati sull'ambiente dello sviluppatore, ricreando la stessa situazione e aggiungendo un nuovo changelog, che superer\u00e0 il problema.<br \/>\n<img decoding=\"async\" alt=\"Come non spararsi sui piedi usando Liquibase\" src=\"\/wp-content\/uploads\/2020\/02\/b5d28a940a7a35b6cd7a819a8e68f027.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<\/ul>\n<p><\/p>\n<p>In generale, pi\u00f9 la base di dati \u00e8 simile a quella del server di produzione, minori saranno le probabilit\u00e0 che i problemi di migrazione si verifichino in modo significativo. E, naturalmente, prima di inviare il changelog nel repository, vale la pena pensarci su pi\u00f9 volte per assicurarsi che non danneggi nulla. <\/p>\n<p><\/p>\n<h3 id=\"situaciya-3-liquibase-nachinaet-primenyatsya-uzhe-posle-vyhoda-v-prodakshn\">Situazione 3. Liquibase inizia ad essere utilizzato solo dopo il passaggio in produzione.<\/h3>\n<p><\/p>\n<p>Immaginiamo che il team leader abbia chiesto a Pety\u00e0 di integrare Liquibase nel progetto, tuttavia il progetto \u00e8 gi\u00e0 in produzione e c'\u00e8 gi\u00e0 una struttura della base dati esistente.<\/p>\n<p><\/p>\n<p>Di conseguenza, il problema \u00e8 che su qualsiasi nuovo server o macchina degli sviluppatori, i dati di queste tabelle devono essere ricreati da zero, mentre l'ambiente esistente deve rimanere in uno stato consistente, pronto ad accogliere nuovi changelog. <\/p>\n<p><\/p>\n<h4 id=\"kak-reshat-2\">Come procedere<\/h4>\n<p><\/p>\n<p>Qui ci sono anche diversi percorsi:<\/p>\n<p><\/p>\n<ul>\n<li>Il primo e pi\u00f9 ovvio \u00e8 avere uno script separato che deve essere applicato manualmente durante l'inizializzazione di un nuovo ambiente. <\/li>\n<li>Il secondo, meno ovvio, \u00e8 avere una migrazione di Liquibase che si trova in un altro contesto di Liquibase e applicarla. Maggiori dettagli su Liquibase Context possono essere letti qui: <noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/documentation\/contexts.html\">https:\/\/www.liquibase.org\/documentation\/contexts.html<\/a><\/noindex>. In generale, \u00e8 un meccanismo interessante che pu\u00f2 essere applicato con successo, ad esempio, per il testing. <\/li>\n<li>Il terzo approccio consiste in diversi passaggi. Prima di tutto, \u00e8 necessario creare una migrazione per le tabelle gi\u00e0 esistenti. Successivamente, deve essere applicata in un ambiente specifico, in modo da ottenere il suo checksum. Il passaggio successivo consiste nell'inizializzare le tabelle di Liquibase vuote sul nostro server non vuoto, e nella tabella con la cronologia delle applicazioni dei changeset si pu\u00f2 manualmente inserire un record di un changeset 'in quanto applicato' con le modifiche gi\u00e0 presenti nel database. In questo modo, sulla server esistente, la cronologia inizier\u00e0 dalla versione 2, mentre tutti i nuovi ambienti si comporteranno in modo identico.<br \/>\n<img decoding=\"async\" alt=\"Come non spararsi sui piedi usando Liquibase\" src=\"\/wp-content\/uploads\/2020\/02\/78881ee56a6ee3ba4e0cd1089598c3c7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"situaciya-4-migracii-stanovyatsya-ogromnymi-i-ne-uspevayut-vypolnyatsya\">Situazione 4. Le migrazioni diventano enormi e non riescono a essere completate in tempo.<\/h3>\n<p><\/p>\n<p>All'inizio dello sviluppo del servizio, di solito si utilizza Liquibase come dipendenza esterna, e tutte le migrazioni vengono elaborate all'avvio dell'applicazione. Tuttavia, col passare del tempo, potresti incontrare i seguenti casi:<\/p>\n<p><\/p>\n<ul>\n<li>Le migrazioni diventano enormi e richiedono molto tempo per essere completate.<\/li>\n<li>Si presenta la necessit\u00e0 di eseguire migrazioni in ambienti distribuiti, ad esempio, su pi\u00f9 istanze di server di database contemporaneamente.<br \/>\nIn questo caso, l'applicazione prolungata delle migrazioni porter\u00e0 a un timeout all'avvio dell'applicazione. Inoltre, applicare le migrazioni per ogni istanza dell'applicazione separatamente pu\u00f2 causare che diversi server si trovino in uno stato non sincronizzato. <\/li>\n<\/ul>\n<p><\/p>\n<h4 id=\"kak-reshat-3\">Come procedere<\/h4>\n<p><\/p>\n<p>In questi casi, il tuo progetto \u00e8 gi\u00e0 grande, forse anche maturo, e Liquibase inizia a funzionare come uno strumento esterno separato. Infatti, Liquibase come libreria viene assemblato in un file jar e pu\u00f2 funzionare sia come dipendenza all'interno del progetto, sia in modo autonomo. <\/p>\n<p><\/p>\n<p>In modalit\u00e0 autonoma, puoi delegare l'applicazione delle migrazioni al tuo ambiente CI\/CD o ai robusti sistemi dei tuoi amministratori di sistema o specialisti nel dispiegamento. Per questo, sar\u00e0 necessaria la riga di comando di Liquibase. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/documentation\/command_line.html\">https:\/\/www.liquibase.org\/documentation\/command_line.html<\/a><\/noindex>. In questa modalit\u00e0 \u00e8 possibile avviare l'applicazione solo dopo che tutte le migrazioni necessarie sono state eseguite.<\/p>\n<p><\/p>\n<h2 id=\"vyvod\">Risultato<\/h2>\n<p><\/p>\n<p>In realt\u00e0, ci possono essere molte pi\u00f9 insidie quando si lavora con le migrazioni del database, e molte di esse richiedono un approccio creativo. \u00c8 importante capire che, se si utilizza correttamente lo strumento, la maggior parte di queste insidie pu\u00f2 essere evitata. Personalmente, ho affrontato in vari modi tutti i problemi elencati, e alcuni di essi sono stati il risultato dei miei errori. Questo accade principalmente per distrazione, ma a volte anche per un'incapacit\u00e0 criminale nel utilizzare lo strumento.<\/p>\n<p>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/epam_systems\/blog\/489198\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u044b\u043b\u043e, \u0438 \u0432\u043e\u0442 \u043e\u043f\u044f\u0442\u044c! \u041d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Liquibase \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0430, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c. \u041a\u0430\u043a \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u043d\u0435 \u0432\u0441\u0435 \u043c\u043e\u043b\u043e\u0434\u044b\u0435 \u0447\u043b\u0435\u043d\u044b \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0443\u043c\u0435\u044e\u0442 \u0435\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u042f \u043f\u0440\u043e\u0432\u0451\u043b \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u0432\u043e\u0440\u043a\u0448\u043e\u043f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0442\u0435\u043c \u0440\u0435\u0448\u0438\u043b \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0432 \u0441\u0442\u0430\u0442\u044c\u044e. \u0421\u0442\u0430\u0442\u044c\u044f \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0441\u043e\u0432\u0435\u0442\u044b \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0442\u0440\u0435\u0445 \u0441\u0430\u043c\u044b\u0445 \u044f\u0432\u043d\u044b\u0445 \u043b\u043e\u0432\u0443\u0448\u0435\u043a, \u0432 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":70974,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-70973","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.10 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u044b\u043b\u043e, \u0438 \u0432\u043e\u0442 \u043e\u043f\u044f\u0442\u044c! \u041d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Liquibase \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0430, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c. \u041a\u0430\u043a \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u043d\u0435 \u0432\u0441\u0435 \u043c\u043e\u043b\u043e\u0434\u044b\u0435 \u0447\u043b\u0435\u043d\u044b \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0443\u043c\u0435\u044e\u0442 \u0435\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u042f \u043f\u0440\u043e\u0432\u0451\u043b \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u0432\u043e\u0440\u043a\u0448\u043e\u043f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0442\u0435\u043c \u0440\u0435\u0448\u0438\u043b \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0432 \u0441\u0442\u0430\u0442\u044c\u044e. \u0421\u0442\u0430\u0442\u044c\u044f \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0441\u043e\u0432\u0435\u0442\u044b \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0442\u0440\u0435\u0445 \u0441\u0430\u043c\u044b\u0445 \u044f\u0432\u043d\u044b\u0445 \u043b\u043e\u0432\u0443\u0448\u0435\u043a, \u0432\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/kak-ne-vystrelit-sebe-v-nogu-ispolzuya-liquibase\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"it_IT\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041a\u0430\u043a \u043d\u0435 \u0432\u044b\u0441\u0442\u0440\u0435\u043b\u0438\u0442\u044c \u0441\u0435\u0431\u0435 \u0432 \u043d\u043e\u0433\u0443, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f Liquibase | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u044b\u043b\u043e, \u0438 \u0432\u043e\u0442 \u043e\u043f\u044f\u0442\u044c! \u041d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Liquibase \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0430, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c. \u041a\u0430\u043a \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u043d\u0435 \u0432\u0441\u0435 \u043c\u043e\u043b\u043e\u0434\u044b\u0435 \u0447\u043b\u0435\u043d\u044b \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0443\u043c\u0435\u044e\u0442 \u0435\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u042f \u043f\u0440\u043e\u0432\u0451\u043b \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u0432\u043e\u0440\u043a\u0448\u043e\u043f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0442\u0435\u043c \u0440\u0435\u0448\u0438\u043b \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0432 \u0441\u0442\u0430\u0442\u044c\u044e. \u0421\u0442\u0430\u0442\u044c\u044f \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0441\u043e\u0432\u0435\u0442\u044b \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0442\u0440\u0435\u0445 \u0441\u0430\u043c\u044b\u0445 \u044f\u0432\u043d\u044b\u0445 \u043b\u043e\u0432\u0443\u0448\u0435\u043a, \u0432\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/kak-ne-vystrelit-sebe-v-nogu-ispolzuya-liquibase\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-02-22T21:58:26+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-03-03T13:14:41+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Come non spararsi sui piedi usando Liquibase | ProHoster","description":"Non \u00e8 mai successo, eppure ecco di nuovo! In un nuovo progetto abbiamo deciso di utilizzare Liquibase sin dall'inizio per evitare problemi in futuro. A quanto pare, non tutti i membri giovani del team sanno usarlo correttamente. Ho tenuto un workshop interno, che poi ho deciso di trasformare in un articolo. L'articolo include consigli utili e la descrizione delle tre insidie pi\u00f9 evidenti, in","canonical_url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/kak-ne-vystrelit-sebe-v-nogu-ispolzuya-liquibase","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"it_IT","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041a\u0430\u043a \u043d\u0435 \u0432\u044b\u0441\u0442\u0440\u0435\u043b\u0438\u0442\u044c \u0441\u0435\u0431\u0435 \u0432 \u043d\u043e\u0433\u0443, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f Liquibase | ProHoster","og:description":"\u041d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u044b\u043b\u043e, \u0438 \u0432\u043e\u0442 \u043e\u043f\u044f\u0442\u044c! \u041d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Liquibase \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0430, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c. \u041a\u0430\u043a \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u043d\u0435 \u0432\u0441\u0435 \u043c\u043e\u043b\u043e\u0434\u044b\u0435 \u0447\u043b\u0435\u043d\u044b \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0443\u043c\u0435\u044e\u0442 \u0435\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u042f \u043f\u0440\u043e\u0432\u0451\u043b \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u0432\u043e\u0440\u043a\u0448\u043e\u043f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0442\u0435\u043c \u0440\u0435\u0448\u0438\u043b \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0432 \u0441\u0442\u0430\u0442\u044c\u044e. \u0421\u0442\u0430\u0442\u044c\u044f \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0441\u043e\u0432\u0435\u0442\u044b \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0442\u0440\u0435\u0445 \u0441\u0430\u043c\u044b\u0445 \u044f\u0432\u043d\u044b\u0445 \u043b\u043e\u0432\u0443\u0448\u0435\u043a, \u0432","og:url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/kak-ne-vystrelit-sebe-v-nogu-ispolzuya-liquibase","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-02-22T21:58:26+00:00","article:modified_time":"2020-03-03T13:14:41+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"70973","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 19:10:24","updated":"2022-09-28 08:39:22"},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/70973","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/comments?post=70973"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/70973\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media\/70974"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media?parent=70973"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/categories?post=70973"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/tags?post=70973"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}