{"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\/es\/blog\/administrirovanie\/kak-ne-vystrelit-sebe-v-nogu-ispolzuya-liquibase","title":{"rendered":"C\u00f3mo no dispararte en el pie al usar Liquibase","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>\u00a1Nunca hab\u00eda pasado, y aqu\u00ed estamos de nuevo!<\/p>\n<p><\/p>\n<p>En nuestro nuevo proyecto decidimos usar Liquibase desde el principio para evitar problemas en el futuro. Resulta que no todos los miembros j\u00f3venes del equipo saben c\u00f3mo usarlo correctamente. Organic\u00e9 un taller interno que luego decid\u00ed convertir en un art\u00edculo. <\/p>\n<p><\/p>\n<p>El art\u00edculo incluye consejos \u00fatiles y la descripci\u00f3n de las tres trampas m\u00e1s evidentes en las que se puede caer al trabajar con herramientas de migraci\u00f3n de bases de datos relacionales, en particular Liquibase. Est\u00e1 dirigido a desarrolladores Java de nivel Junior y Middle; para desarrolladores m\u00e1s experimentados puede ser interesante para estructurar y repasar lo que probablemente ya conocen. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"C\u00f3mo no dispararte en el pie al usar 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 y Flyway son las principales tecnolog\u00edas competidoras para el control de versiones de estructuras relacionales en el mundo de Java. La primera es completamente gratuita, y en la pr\u00e1ctica, suele ser la elegida para su uso, por lo que Liquibase se convierte en la protagonista de esta publicaci\u00f3n. Sin embargo, algunas de las pr\u00e1cticas descritas pueden ser universales, dependiendo de la arquitectura de tu aplicaci\u00f3n. <\/p>\n<p><\/p>\n<p>Las migraciones de estructuras relacionales son una forma surgida por necesidad para lidiar con la rigidez de los almacenes de datos relacionales. En la era de la moda de la programaci\u00f3n orientada a objetos, trabajar con bases de datos implicaba que describ\u00edamos un esquema una vez y no lo \u00edbamos a tocar m\u00e1s. Pero la realidad es siempre cambiante, y los cambios en la estructura de las tablas son bastante frecuentes. Naturalmente, el proceso puede ser doloroso y desagradable. <\/p>\n<p><\/p>\n<p>No profundizar\u00e9 en la descripci\u00f3n de la tecnolog\u00eda ni en las instrucciones para a\u00f1adir la biblioteca a tu proyecto; ya se han escrito suficientes art\u00edculos sobre este tema:<\/p>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/460377\/\">Uso de Liquibase para gestionar la estructura de la base de datos en una aplicaci\u00f3n Spring Boot. Parte 1<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/460907\/\">Uso de Liquibase para gestionar la estructura de la base de datos en una aplicaci\u00f3n Spring Boot. Parte 2<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/436994\/\">Liquibase y Maven<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/330662\/\">Enfoques para la versionado de cambios en la base de datos<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/271719\/\">Spring MVC\/Security, REST, Hibernate, Liquibase se ejecutan en dos l\u00edneas<\/a><\/noindex><\/li>\n<\/ul>\n<p><\/p>\n<p>Adem\u00e1s, ya hab\u00eda un excelente art\u00edculo sobre consejos \u00fatiles:<\/p>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/179425\/\">Uso de Liquibase sin dolor de cabeza. 10 consejos de la experiencia de desarrollo real<\/a><\/noindex><\/li>\n<\/ul>\n<p><\/p>\n<h2 id=\"sovety\">Consejos<\/h2>\n<p><\/p>\n<p>Quiero compartir mis consejos y comentarios que nacieron a trav\u00e9s del sudor, la sangre y el dolor de resolver problemas de migraci\u00f3n.<\/p>\n<p><\/p>\n<h3 id=\"1--pered-rabotoy-sleduet-oznakomitsya-s-razdelom-luchshih-praktik-na-saytehttpswwwliquibaseorgbestpracticeshtml-liquibase\">1. Antes de comenzar, es recomendable revisar la secci\u00f3n de mejores pr\u00e1cticas en <noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/bestpractices.html\">el sitio web<\/a><\/noindex> Liquibase<\/h3>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/bestpractices.html\">All\u00ed<\/a><\/noindex> se describen cosas simples pero muy importantes, sin las cuales el uso de la biblioteca puede complicarle la vida. Por ejemplo, un enfoque no estructurado para gestionar los changsets con el tiempo conducir\u00e1 a confusiones y migraciones rotas. Si los cambios en la estructura de la base de datos y la l\u00f3gica de los servicios que dependen unos de otros no se implementan simult\u00e1neamente, hay una gran probabilidad de que esto conduzca a pruebas fallidas o un entorno roto. Adem\u00e1s, las recomendaciones para el uso de Liquibase en el sitio oficial incluyen un apartado sobre el desarrollo y verificaci\u00f3n de scripts de rollback junto con los scripts principales de migraci\u00f3n. Y en el art\u00edculo <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/178665\/\">https:\/\/habr.com\/ru\/post\/178665\/<\/a><\/noindex> hay ejemplos de c\u00f3digo relacionados con migraciones y el mecanismo de rollback. <\/p>\n<p><\/p>\n<h3 id=\"2-esli-nachali-ispolzovat-sredstva-migracii--ne-dopuskayte-manualnyh-ispravleniy-v-strukture-bazy\">2. Si ha comenzado a utilizar herramientas de migraci\u00f3n, no permita correcciones manuales en la estructura de la base de datos.<\/h3>\n<p><\/p>\n<p>Como se dice: \u00abUna vez Persil, siempre Persil\u00bb. Si la base de datos de su aplicaci\u00f3n comenz\u00f3 a gestionarse mediante Liquibase, cualquier cambio manual llevar\u00e1 inmediatamente a un estado inconsistente, y el nivel de confianza en los changsets ser\u00e1 igual a cero. Los riesgos potenciales son varias horas gastadas en recuperar la base de datos, y en el peor de los casos, un servidor arruinado. Si en su equipo hay un DBA arquitecto de la \u00abvieja guardia\u00bb, expl\u00edquele con paciencia y reflexi\u00f3n c\u00f3mo las cosas se complicar\u00e1n si edita la base a su antojo desde un SQL Developer hipot\u00e9tico. <\/p>\n<p><\/p>\n<h3 id=\"3-esli-chendzhset-uzhe-byl-zapushen-v-repozitoriy-izbegayte-redaktirovaniya\">3. Si el changset ya ha sido subido al repositorio, evite editarlo.<\/h3>\n<p><\/p>\n<p>Si otro desarrollador hizo un pull y aplic\u00f3 un changset que luego ser\u00e1 editado, seguramente recordar\u00e1 su nombre con cari\u00f1o cuando obtenga un error al iniciar la aplicaci\u00f3n. Si la edici\u00f3n del changset se filtra de alguna manera en el desarrollo, tendr\u00e1 que recurrir a una peligrosa serie de hotfixes. La esencia del problema radica en la validaci\u00f3n de los cambios por medio de la suma de verificaci\u00f3n \u2014 el mecanismo principal de Liquibase. Al editar el c\u00f3digo del changset, cambia la suma de verificaci\u00f3n. La edici\u00f3n de changsets solo es posible cuando existe la capacidad de desplegar toda la base desde cero sin p\u00e9rdida de datos. En tal caso, el refactorizaci\u00f3n del c\u00f3digo SQL o XML puede, por el contrario, facilitar la vida y hacer que las migraciones sean m\u00e1s legibles. Un ejemplo podr\u00eda ser la situaci\u00f3n en la que, al inicio de la aplicaci\u00f3n, el esquema inicial de la base de datos se acord\u00f3 dentro del equipo. <\/p>\n<p><\/p>\n<h3 id=\"4--imey-proverennye-bekapy-baz-dannyh-esli-eto-vozmozhno\">4. Ten copias de seguridad comprobadas de bases de datos, si es posible<\/h3>\n<p><\/p>\n<p>Aqu\u00ed, creo que todo est\u00e1 claro. En caso de que la migraci\u00f3n falle, se podr\u00e1 revertir todo. Liquibase tiene una herramienta para deshacer cambios, pero los scripts de reversi\u00f3n los escribe el mismo desarrollador, y pueden haber problemas con ellos tan f\u00e1cilmente como con los scripts del conjunto de cambios principal. Esto significa que es \u00fatil tener copias de seguridad en cualquier caso. <\/p>\n<p><\/p>\n<h3 id=\"5-ispolzuy-proverennye-bekapy-baz-dannyh-v-razrabotke-esli-eto-vozmozhno\">5. Utiliza copias de seguridad comprobadas de bases de datos en desarrollo, si es posible<\/h3>\n<p><\/p>\n<p>Si esto no va en contra de los contratos y la privacidad, no hay datos personales en la base, y no pesa como dos soles, antes de aplicar la migraci\u00f3n en los servidores en vivo se puede verificar c\u00f3mo funcionar\u00e1 en la m\u00e1quina del desarrollador y determinar casi el 100% de los problemas potenciales durante la migraci\u00f3n. <\/p>\n<p><\/p>\n<h3 id=\"6-obschaysya-s-drugimi-razrabotchikami-v-komande\">6. Comun\u00edcate con otros desarrolladores en el equipo<\/h3>\n<p><\/p>\n<p>En un proceso de desarrollo bien organizado, todos en el equipo saben qu\u00e9 est\u00e1 haciendo cada uno. En realidad, a menudo no es as\u00ed, por lo que, si est\u00e1s preparando cambios en la estructura de la base de datos dentro de tu tarea, ser\u00eda deseable informar a todo el equipo sobre esto. Si alguien est\u00e1 haciendo cambios en paralelo, deber\u00edas organizarte cuidadosamente. Es importante comunicarte con los colegas tambi\u00e9n despu\u00e9s de terminar el trabajo, no solo al inicio. Muchos problemas potenciales con los conjuntos de cambios pueden resolverse en la etapa de revisi\u00f3n de c\u00f3digo. <\/p>\n<p><\/p>\n<h3 id=\"7-dumay-chto-delaesh\">7. \u00a1Piensa en lo que haces!<\/h3>\n<p><\/p>\n<p>Puede parecer un consejo obvio, aplicable a cualquier situaci\u00f3n. Sin embargo, muchos problemas podr\u00edan haberse evitado si el desarrollador analizara de nuevo lo que est\u00e1 haciendo y qu\u00e9 impacto podr\u00eda tener. Trabajar con migraciones siempre requiere atenci\u00f3n adicional y cuidado. <\/p>\n<p><\/p>\n<h2 id=\"lovushki\">Trampas<\/h2>\n<p><\/p>\n<p>Veamos ahora las trampas t\u00edpicas en las que se puede caer si no se siguen los consejos anteriores, y \u00bfqu\u00e9 hacer al respecto?<\/p>\n<p><\/p>\n<h3 id=\"situaciya-1-dva-razrabotchika-pytayutsya-odnovremenno-dobavlyat-novye-chendzhsety\">Situaci\u00f3n 1. Dos desarrolladores intentan agregar nuevos conjuntos de cambios al mismo tiempo<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"C\u00f3mo no dispararte en el pie al usar Liquibase\" src=\"\/wp-content\/uploads\/2020\/02\/20706fc970510bc06634fa001a4c7ceb.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nVasya y Petya quieren crear el conjunto de cambios de la versi\u00f3n 4, sin saber el uno del otro. Han realizado cambios en la estructura de la base de datos y han lanzado una solicitud de extracci\u00f3n, con diferentes archivos de conjunto de cambios. A continuaci\u00f3n, se propone el siguiente mecanismo de acci\u00f3n:<\/p>\n<p><\/p>\n<h4 id=\"kak-reshat\">C\u00f3mo resolver<\/h4>\n<p><\/p>\n<ol>\n<li>De alguna manera, los colegas deben acordar en qu\u00e9 orden deben ir sus conjuntos de cambios, por ejemplo, el de Petya deber\u00eda aplicarse primero. <\/li>\n<li>Alguien debe agregar el segundo a s\u00ed mismo y marcar el changeSet de Vasya con la versi\u00f3n 5. Esto se puede hacer a trav\u00e9s de Cherry Pick o un merge cuidadoso. <\/li>\n<li>Despu\u00e9s de los cambios, siempre se debe verificar la validez de las acciones realizadas.<br \/>\nEn realidad, los mecanismos de Liquibase permitir\u00e1n tener en el repositorio dos changeSets de la versi\u00f3n 4, por lo que se puede dejar todo como est\u00e1. Es decir, tendr\u00e1 simplemente dos cambios de la versi\u00f3n 4 con diferentes nombres. Con este enfoque, posteriormente se vuelve muy dif\u00edcil orientarse en las versiones de la base de datos. <\/li>\n<\/ol>\n<p><\/p>\n<p>Adem\u00e1s, Liquibase, como la casa de los hobbits, guarda muchos secretos. Uno de ellos es la clave validCheckSum, que apareci\u00f3 con la versi\u00f3n 1.7 y permite especificar un valor de hash v\u00e1lido para un changeSet determinado, independientemente de lo que est\u00e9 almacenado en la base de datos. Documentaci\u00f3n <noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/documentation\/changeset.html\">https:\/\/www.liquibase.org\/documentation\/changeset.html<\/a><\/noindex> dice lo siguiente:<\/p>\n<p><\/p>\n<blockquote><p>Agrega un checksum que se considere v\u00e1lido para este changeSet, independientemente de lo que est\u00e9 almacenado en la base de datos. Se utiliza principalmente cuando necesitas cambiar un changeSet y no deseas que se produzcan errores en bases de datos en las que ya se ha ejecutado (no es un procedimiento recomendado).<\/p><\/blockquote>\n<p>S\u00ed, s\u00ed, este procedimiento no se recomienda. Pero a veces un poderoso mago blanco tambi\u00e9n domina t\u00e9cnicas oscuras. <\/p>\n<p><\/p>\n<h3 id=\"situaciya-2-migraciya-kotoraya-zavisit-ot-dannyh\">Situaci\u00f3n 2. Migraci\u00f3n que depende de los datos.<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"C\u00f3mo no dispararte en el pie al usar Liquibase\" src=\"\/wp-content\/uploads\/2020\/02\/31a6eebb55278c0631115bf16483c7b8.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Supongamos que no tiene la oportunidad de utilizar copias de seguridad de bases de datos de servidores en vivo. Petya cre\u00f3 un changeSet, lo verific\u00f3 localmente y, con total confianza en su verdad, hizo un pull request en dev. El l\u00edder del proyecto, por si acaso, pregunt\u00f3 si Petya lo hab\u00eda verificado, y luego lo fusion\u00f3. Pero el despliegue en el servidor de dev fall\u00f3.<\/p>\n<p><\/p>\n<p>En realidad, esto es posible, y nadie est\u00e1 a salvo de ello. Esto ocurre cuando las modificaciones en la estructura de las tablas est\u00e1n de alguna manera vinculadas a datos espec\u00edficos de la base de datos. Es evidente que si la base de datos de Petya solo est\u00e1 llena de datos de prueba, puede que no cubra todos los casos problem\u00e1ticos. Por ejemplo, al eliminar una tabla, se descubre que hay registros en otras tablas mediante una clave for\u00e1nea, relacionados con registros en la tabla eliminada. O al cambiar el tipo de columna, se descubren que no el 100% de los datos pueden convertirse al nuevo tipo. <\/p>\n<p><\/p>\n<h4 id=\"kak-reshat-1\">C\u00f3mo resolver<\/h4>\n<p><\/p>\n<ul>\n<li>Escribir scripts especiales que se apliquen una sola vez junto con la migraci\u00f3n y lleven los datos a su forma adecuada. Este es un enfoque general para resolver el problema de la migraci\u00f3n de datos a nuevas estructuras ya despu\u00e9s de aplicar las migraciones, aunque algo similar tambi\u00e9n puede aplicarse antes, en casos particulares. Por supuesto, este enfoque no siempre est\u00e1 disponible, ya que editar datos en servidores en vivo puede ser peligroso e incluso desastroso. <\/li>\n<li>Otro camino complicado es editar el changset existente. La dificultad radica en que todas las bases de datos en las que ya se ha aplicado en su forma actual tendr\u00e1n que ser restauradas. Es bastante posible que todo el equipo backend se vea obligado a reinstalar la base de datos desde cero de manera local. <\/li>\n<li>Y el camino m\u00e1s universal es trasladar el problema de los datos al entorno del desarrollador, recreando la misma situaci\u00f3n y a\u00f1adiendo un nuevo changset que permita sortear el problema antes del que se hab\u00eda roto.<br \/>\n<img decoding=\"async\" alt=\"C\u00f3mo no dispararte en el pie al usar Liquibase\" src=\"\/wp-content\/uploads\/2020\/02\/b5d28a940a7a35b6cd7a819a8e68f027.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<\/ul>\n<p><\/p>\n<p>En general, cuanto m\u00e1s se asemeje la base de datos en cuanto a composici\u00f3n de datos a la base del servidor de producci\u00f3n, menor ser\u00e1 la probabilidad de que los problemas con las migraciones se extiendan. Y, por supuesto, antes de enviar el changset al repositorio, vale la pena pensarlo dos veces: \u00bfno romper\u00e1 nada? <\/p>\n<p><\/p>\n<h3 id=\"situaciya-3-liquibase-nachinaet-primenyatsya-uzhe-posle-vyhoda-v-prodakshn\">Situaci\u00f3n 3. Liquibase comienza a aplicarse ya despu\u00e9s de salir a producci\u00f3n.<\/h3>\n<p><\/p>\n<p>Supongamos que el l\u00edder de equipo pidi\u00f3 a Petya conectar Liquibase al proyecto, sin embargo, el proyecto ya est\u00e1 en producci\u00f3n y existe una estructura de base de datos ya existente.<\/p>\n<p><\/p>\n<p>Por lo tanto, el problema radica en que en cualquier nuevo servidor o m\u00e1quina de desarrolladores, los datos de las tablas deben recrearse desde cero, y el entorno ya existente debe permanecer en un estado consistente, listo para aceptar nuevos changsets. <\/p>\n<p><\/p>\n<h4 id=\"kak-reshat-2\">C\u00f3mo resolver<\/h4>\n<p><\/p>\n<p>Aqu\u00ed tambi\u00e9n hay varios caminos:<\/p>\n<p><\/p>\n<ul>\n<li>El primero y m\u00e1s obvio es tener un script separado que deba aplicarse manualmente al inicializar un nuevo entorno. <\/li>\n<li>El segundo, menos obvio, es tener una migraci\u00f3n de Liquibase que se encuentre en otro contexto de Liquibase y aplicarla. M\u00e1s sobre el contexto de Liquibase se puede leer aqu\u00ed: <noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/documentation\/contexts.html\">https:\/\/www.liquibase.org\/documentation\/contexts.html<\/a><\/noindex>. En general, es un mecanismo interesante que puede aplicarse exitosamente, por ejemplo, para pruebas. <\/li>\n<li>El tercer camino consiste en varios pasos. Primero, se debe crear una migraci\u00f3n para las tablas que ya existen. Luego, debe aplicarse en alg\u00fan entorno y as\u00ed se obtendr\u00e1 su suma hash. El siguiente paso es inicializar las tablas vac\u00edas de Liquibase en nuestro servidor que no est\u00e1 vac\u00edo, y se puede agregar manualmente un registro en la tabla de historia de aplicaci\u00f3n de cambios como si el cambio ya se hubiera aplicado con los cambios que ya existen en la base de datos. De esta manera, en el servidor ya existente, el conteo de la historia comenzar\u00e1 desde la versi\u00f3n 2, y todos los nuevos entornos se comportar\u00e1n de manera id\u00e9ntica.<br \/>\n<img decoding=\"async\" alt=\"C\u00f3mo no dispararte en el pie al usar 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\">Situaci\u00f3n 4. Las migraciones se vuelven enormes y no se logran ejecutar a tiempo.<\/h3>\n<p><\/p>\n<p>Al inicio del desarrollo del servicio, generalmente, Liquibase se utiliza como una dependencia externa, y todas las migraciones se procesan al iniciar la aplicaci\u00f3n. Sin embargo, con el tiempo, puede encontrarse con los siguientes casos:<\/p>\n<p><\/p>\n<ul>\n<li>Las migraciones se vuelven enormes y tardan mucho tiempo en ejecutarse.<\/li>\n<li>Surge la necesidad de migrar en entornos distribuidos, por ejemplo, en varias instancias de servidores de bases de datos al mismo tiempo.<br \/>\nEn este caso, la aplicaci\u00f3n prolongada de migraciones provocar\u00e1 un time-out al iniciar la aplicaci\u00f3n. Adem\u00e1s, aplicar migraciones para cada instancia de aplicaci\u00f3n por separado puede hacer que diferentes servidores queden en un estado fuera de sincronizaci\u00f3n. <\/li>\n<\/ul>\n<p><\/p>\n<h4 id=\"kak-reshat-3\">C\u00f3mo resolver<\/h4>\n<p><\/p>\n<p>En tales casos, su proyecto ya es grande, posiblemente incluso maduro, y Liquibase comienza a actuar como una herramienta externa independiente. La cuesti\u00f3n es que Liquibase, como biblioteca, se compila en un archivo jar, y puede funcionar tanto como una dependencia dentro del proyecto como de manera aut\u00f3noma. <\/p>\n<p><\/p>\n<p>En modo aut\u00f3nomo, se puede delegar la aplicaci\u00f3n de migraciones a su entorno CI\/CD o a las fuertes manos de sus administradores de sistemas especializados en despliegue. Para esto necesitar\u00e1 la l\u00ednea de comandos de Liquibase. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/documentation\/command_line.html\">https:\/\/www.liquibase.org\/documentation\/command_line.html<\/a><\/noindex>. En este modo, existe la posibilidad de iniciar la aplicaci\u00f3n ya despu\u00e9s de que se hayan realizado todas las migraciones necesarias.<\/p>\n<p><\/p>\n<h2 id=\"vyvod\">Salida<\/h2>\n<p><\/p>\n<p>En realidad, puede haber muchas m\u00e1s trampas al trabajar con migraciones de base de datos, y muchas de ellas requieren un enfoque creativo. Es importante entender que si se utiliza correctamente la herramienta, se puede evitar la mayor\u00eda de estas trampas. Personalmente, me he enfrentado a todos los problemas mencionados en diferentes formas, y algunos de ellos fueron resultado de mis propios errores. Principalmente, esto sucede, por supuesto, por falta de atenci\u00f3n, pero a veces \u2013 debido a una incapacidad criminal para utilizar la herramienta.<\/p>\n<p>Fuente: <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 5.0.2 - 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.\" \/>\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\/es\/blog\/administrirovanie\/kak-ne-vystrelit-sebe-v-nogu-ispolzuya-liquibase\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"es_ES\" \/>\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.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/es\/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\udd47C\u00f3mo no dispararte en el pie usando Liquibase | ProHoster","description":"Nunca antes hab\u00eda sucedido, \u00a1y aqu\u00ed estamos otra vez! En un nuevo proyecto, decidimos utilizar Liquibase desde el principio para evitar problemas en el futuro.","canonical_url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/kak-ne-vystrelit-sebe-v-nogu-ispolzuya-liquibase","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"es_ES","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.","og:url":"https:\/\/prohoster.info\/es\/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","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/70973","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/comments?post=70973"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/70973\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media\/70974"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media?parent=70973"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/categories?post=70973"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/tags?post=70973"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}