tipos tag remove practices etiquetas create crear best database git version-control postgresql

database - tag - ¿Cómo puedo poner una base de datos en git(control de versiones)?



git tag push (24)

Estoy haciendo una aplicación web, y necesito hacer una rama para algunos cambios importantes, la cosa es que estos cambios requieren cambios en el esquema de la base de datos, así que también me gustaría poner la base de datos completa bajo git.

¿Cómo puedo hacer eso? ¿Existe una carpeta específica que pueda mantener bajo un repositorio de git? ¿Cómo puedo saber cuál? ¿Cómo puedo estar seguro de que estoy poniendo la carpeta correcta?

Necesito estar seguro, porque estos cambios no son compatibles con versiones anteriores; No puedo permitirme el lujo de joder.

La base de datos en mi caso es PostgreSQL.

Editar:

Alguien sugirió realizar copias de seguridad y poner el archivo de copia de seguridad bajo el control de versiones en lugar de la base de datos. Para ser honesto, me resulta muy difícil de tragar.

Tiene que haber una mejor manera.

Actualizar:

De acuerdo, no hay mejor manera, pero todavía no estoy del todo convencido, así que cambiaré la pregunta un poco:

Me gustaría poner toda la base de datos bajo el control de versiones, ¿qué motor de base de datos puedo usar para poder poner la base de datos real bajo el control de versiones en lugar de su volcado?

¿Sería sqlite amigable con git?

Como este es solo el entorno de desarrollo, puedo elegir la base de datos que desee.

Edit2:

Lo que realmente quiero es no rastrear mi historial de desarrollo, sino poder cambiar de mi rama de "nuevos cambios radicales" a la "rama estable actual" y poder, por ejemplo, solucionar algunos errores / problemas, etc. Rama estable. De modo que cuando cambio de ramas, la base de datos se convierte automáticamente en compatible con la rama en la que estoy actualmente. Realmente no me importa mucho los datos reales.


Me gustaría poner toda la base de datos bajo el control de versiones, ¿qué motor de base de datos puedo usar para poder poner la base de datos real bajo el control de versiones en lugar de su volcado?

Esto no es dependiente del motor de base de datos. Por Microsoft SQL Server hay muchos programas de control de versiones. No creo que ese problema se pueda resolver con git, tiene que usar un sistema de control de versión de esquema específico pgsql. No sé si tal cosa existe o no ...


Almacenar cada nivel de cambios en la base de datos bajo el control de versiones de git es como empujar su base de datos completa con cada confirmación y restaurar su base de datos completa con cada extracción. Si su base de datos es tan propensa a cambios cruciales y no puede darse el lujo de perderlos, simplemente puede actualizar sus ganchos pre_commit y post_merge . Hice lo mismo con uno de mis proyectos y puedes encontrar las instrucciones here .


Ante una necesidad similar y aquí está lo que mi investigación sobre sistemas de control de versiones de bases de datos arrojó:

  1. Sqitch - fuente abierta basada en Perl; disponible para todas las bases de datos principales, incluyendo PostgreSQL https://github.com/sqitchers/sqitch
  2. Mahout - solo para PostgreSQL; Control de versión de esquema de base de datos de código abierto. https://github.com/cbbrowne/mahout
  3. Liquibase - otra versión de código abierto de db control sw. Versión gratuita de Datical. http://www.liquibase.org/index.html
  4. Datical - versión comercial de Liquibase - https://www.datical.com/
  5. Flyway por BoxFuse - comercial sw. https://flywaydb.org/
  6. Otro proyecto de código abierto https://gitlab.com/depesz/Versioning Author proporciona una guía aquí: https://www.depesz.com/2010/08/22/versioning/
  7. Red Gate Change Automation - solo para SQL Server. https://www.red-gate.com/products/sql-development/sql-change-automation/

Así es como lo hago:

Ya que tiene una elección libre sobre el tipo de base de datos, use una base de datos como, por ejemplo, firebird.

Cree un DB de plantilla que tenga el esquema que se ajuste a su rama real y almacénelo en su repositorio.

Al ejecutar su aplicación, cree una copia de la plantilla de la base de datos mediante programación, guárdela en otro lugar y simplemente trabaje con esa copia.

De esta manera puede poner su esquema de DB bajo el control de versiones sin los datos. Y si cambias tu esquema solo tienes que cambiar la plantilla DB


Consulte las Bases de datos de refactorización ( http://databaserefactoring.com/ ) para conocer un montón de buenas técnicas para mantener su base de datos en conjunto con los cambios de código.

Basta con decir que estás haciendo las preguntas equivocadas. En lugar de poner su base de datos en git, debe descomponer los cambios en pequeños pasos verificables para que pueda migrar / revertir los cambios de esquema con facilidad.

Si desea tener una capacidad de recuperación completa, debe considerar archivar sus registros WAL de postgres y utilizar el PITR (recuperación en un punto en el tiempo) para reproducir / reenviar transacciones a estados de buena reputación específicos.


Creo que X-Istence está en el camino correcto, pero hay algunas mejoras más que puedes hacer en esta estrategia. Primer uso:

$pg_dump --schema ...

para volcar las tablas, secuencias, etc. y colocar este archivo bajo el control de versiones. Lo utilizará para separar los cambios de compatibilidad entre sus sucursales.

A continuación, realice un volcado de datos para el conjunto de tablas que contienen la configuración requerida para que su aplicación funcione (probablemente debería omitir los datos del usuario, etc.), como los valores predeterminados de formularios y otros datos que no se pueden modificar por el usuario. Puedes hacer esto selectivamente usando:

$pg_dump --table=.. <or> --exclude-table=..

Esta es una buena idea porque el repositorio puede volverse realmente torpe cuando su base de datos llega a 100Mb + cuando se realiza un volcado de datos completo. Una mejor idea es realizar una copia de seguridad de un conjunto de datos más mínimo que necesita para probar su aplicación. Sin embargo, si sus datos predeterminados son muy grandes, esto todavía puede causar problemas.

Si absolutamente necesita colocar copias de seguridad completas en el repositorio, considere hacerlo en una rama fuera de su árbol de origen. Sin embargo, un sistema de respaldo externo con alguna referencia a la svn rev coincidente es probablemente el mejor para esto.

Además, sugiero usar volcados de formato de texto sobre binarios para fines de revisión (al menos para el esquema) ya que son más fáciles de diferenciar. Siempre puede comprimirlos para ahorrar espacio antes de registrarse.

Por último, eche un vistazo a la documentación de copia de seguridad de postgres si aún no lo ha hecho. La forma en que comenta acerca de realizar una copia de seguridad de ''la base de datos'' en lugar de un volcado me hace preguntarme si está pensando en copias de seguridad basadas en el sistema de archivos (consulte la sección 23.2 para ver las advertencias).


Echa un vistazo a RedGate SQL Source Control.

http://www.red-gate.com/products/sql-development/sql-source-control/

Esta herramienta es un complemento de SQL Server Management Studio que le permitirá colocar su base de datos en Source Control con Git.

Es un poco caro a $ 495 por usuario, pero hay una versión de prueba gratuita de 28 días disponible.

NOTA No estoy afiliado a RedGate de ninguna manera.


En lugar de volcar manualmente su base de datos y guardarla en git, use Offscale DataGrove .

DataGrove es básicamente un control de versión de base de datos: realiza un seguimiento de los cambios en toda la base de datos (esquema Y datos) y le permite etiquetar las versiones en su repositorio. Puede usarlo junto con git y hacer que marque una versión cada vez que ingrese el código, y cargue el estado correcto de la base de datos cada vez que tire del código.

Específicamente con respecto a la "Edición 2": con DataGrove simplemente puede tener dos ramas de la base de datos, una para cada una de las ramas de código. Cuando carga una determinada rama del código, DataGrove volverá a crear automáticamente todo el estado de la base de datos, con todos los datos dentro de esa versión / rama. Esto significa que puede cambiar entre ramas de desarrollo con un solo comando simple.


Esta pregunta está bastante respondida, pero me gustaría complementar la respuesta de X-Istence y Dana the Sane con una pequeña sugerencia.

Si necesita un control de revisión con cierto grado de granularidad, por ejemplo, puede acoplar el volcado de texto de las tablas y el esquema con una herramienta como rdiff-backup que hace copias de seguridad incrementales. La ventaja es que, en lugar de almacenar instantáneas de las copias de seguridad diarias, simplemente almacena las diferencias con respecto al día anterior.

Con esto tiene la ventaja del control de revisión y no desperdicia demasiado espacio.

En cualquier caso, usar git directamente en grandes archivos planos que cambian con mucha frecuencia no es una buena solución. Si su base de datos se vuelve demasiado grande, git comenzará a tener algunos problemas para administrar los archivos.


Esto es lo que estoy tratando de hacer en mis proyectos:

  • Datos separados y esquema y datos predeterminados.

La configuración de la base de datos se almacena en un archivo de configuración que no está bajo el control de versión (.gitignore)

Los valores predeterminados de la base de datos (para configurar nuevos proyectos) es un archivo SQL simple bajo el control de versiones.

Para el esquema de base de datos, cree un volcado de esquema de base de datos bajo el control de versión.

La forma más común es tener scripts de actualización que contengan sentencias de SQL, (ALTER Table .. o UPDATE). También debe tener un lugar en su base de datos donde guarde la versión actual de su esquema)

Eche un vistazo a otros grandes proyectos de bases de datos de código abierto (piwik, o su sistema de cms favorito), todos ellos utilizan scripts de actualizaciones (1.sql, 2.sql, 3.sh, 4.php.5.sql)

Pero este es un trabajo que requiere mucho tiempo, debe crear y probar los scripts de actualización y debe ejecutar un script de actualización común que compare la versión y ejecute todos los scripts de actualización necesarios.

Por lo tanto, teóricamente (y eso es lo que estoy buscando) se puede volcar el esquema de la base de datos después de cada cambio (manualmente, conjob, git hooks (tal vez antes de confirmar)) (y solo en algunos casos muy especiales, crear actualizaciones)

Después de eso, en su updatecript común (ejecute los updatescripts normales, para los casos especiales) y luego compare los esquemas (el volcado y la base de datos actual) y luego genere automáticamente los estados ALTER necesarios. Hay algunas herramientas que pueden hacer esto ya, pero aún no han encontrado una buena.


Estoy empezando a pensar en una solución realmente simple, ¡no sé por qué no lo pensé antes!

  • Duplique la base de datos, (tanto el esquema como los datos).
  • En la rama para los nuevos cambios mayores, simplemente cambie la configuración del proyecto para usar la nueva base de datos duplicada.

De esta manera puedo cambiar de rama sin preocuparme por los cambios en el esquema de la base de datos.

EDITAR:

Por duplicado, me refiero a crear otra base de datos con un nombre diferente (como my_db_2 ); No haciendo un basurero ni nada de eso.



Hay una herramienta que está en desarrollo llamada Klonio , cuya versión beta está disponible para su uso. Es compatible con MongoDB y MySQL a partir de ahora.

Por supuesto, tiene integración con git y puede hacer una instantánea del esquema solo o incluso de los datos incluidos.


He lanzado una herramienta para sqlite que hace lo que estás pidiendo. Utiliza un controlador de diferencias personalizado que aprovecha la herramienta de proyectos sqlite ''sqldiff'', los UUID como claves principales, y deja fuera el rowid de sqlite. Todavía está en alfa, por lo que se agradece la opinión.

Postgres y mysql son más complicados, ya que los datos binarios se guardan en varios archivos y es posible que ni siquiera sean válidos si pudiera hacer una instantánea.

https://github.com/cannadayr/git-sqlite


Lo que hago en mis proyectos personales es que almaceno toda mi base de datos en Dropbox y luego apunto el flujo de trabajo MAMP, WAMP para usarla directamente desde allí. De esta forma, la base de datos siempre estará actualizada donde sea que necesite hacer algo de desarrollo. Pero eso es solo para dev! Live sites está usando su propio servidor para ese curso! :)


Lo que quieres, en espíritu, es quizás algo como Post Facto , que almacena versiones de una base de datos en una base de datos. Compruebe esta presentation .

Aparentemente, el proyecto nunca fue a ninguna parte, por lo que probablemente no te ayude de inmediato, pero es un concepto interesante. Me temo que hacer esto correctamente sería muy difícil, porque incluso la versión 1 tendría que tener todos los detalles correctos para que la gente confíe su trabajo.


Me he encontrado con esta pregunta, ya que tengo un problema similar, donde algo que se aproxima a una estructura de directorio basada en bases de datos, almacena "archivos" y necesito git para administrarlo. Se distribuye, a través de una nube, usando replicación, por lo tanto, su punto de acceso será a través de MySQL.

La esencia de las respuestas anteriores parece sugerir, de manera similar, una solución alternativa al problema planteado, qué tipo de punto no tiene sentido, de usar Git para administrar algo en una base de datos, por lo que intentaré responder esa pregunta.

Git es un sistema que, en esencia, almacena una base de datos de deltas (diferencias), que se pueden volver a montar, en orden, para reproducir un contexto. El uso normal de git supone que el contexto es un sistema de archivos, y esos deltas son dif en ese sistema de archivos, pero en realidad todo git es una base de datos jerárquica de deltas (jerárquica, porque en la mayoría de los casos cada delta es una confirmación con al menos 1 padres, dispuestos en un árbol).

Mientras pueda generar un delta, en teoría, git puede almacenarlo. Normalmente, el problema es que git espera que el contexto, en el que está generando delta, sea un sistema de archivos, y de manera similar, cuando se registra un punto en la jerarquía de git, se espera generar un sistema de archivos.

Si desea administrar el cambio, en una base de datos, tiene 2 problemas discretos, y los abordaría por separado (si fuera usted). El primero es el esquema, el segundo es la información (aunque en su pregunta, usted indica que la información no es algo que le preocupa). Un problema que tuve en el pasado era una base de datos de Dev y Prod, donde Dev podía realizar cambios incrementales en el esquema, y ​​esos cambios tenían que documentarse en CVS y promocionarse para vivir, junto con adiciones a uno de varios mesas. Lo hicimos teniendo una tercera base de datos, llamada Cruise, que contenía solo los datos estáticos. En cualquier punto, se pudo comparar el esquema de Dev y Cruise, y tuvimos un script para tomar la diferencia de esos 2 archivos y producir un archivo SQL que contenía las declaraciones ALTER, para aplicarlo. De manera similar, cualquier dato nuevo, podría ser destilado a un archivo SQL que contenga comandos INSERT. Mientras los campos y las tablas solo se agreguen, y nunca se eliminen, el proceso podría automatizar la generación de las sentencias de SQL para aplicar el delta.

El mecanismo por el cual git genera deltas es diff y el mecanismo por el cual combina 1 o más deltas con un archivo, se llama merge . Si puede encontrar un método para diferenciar y fusionar desde un contexto diferente, git debería funcionar, pero como se ha discutido, puede que prefiera una herramienta que lo haga por usted. Mi primer pensamiento para resolver eso es este https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration#External-Merge-and-Diff-Tools que detalla cómo reemplazar el diff interno de git y herramienta de fusión. Actualizaré esta respuesta, ya que se me ocurre una mejor solución al problema, pero en mi caso solo tengo que gestionar los cambios de datos, en la medida en que un almacén de archivos basado en bases de datos puede cambiar, por lo que mi solución Puede que no sea exactamente lo que necesitas.


No puede hacerlo sin atomicidad, y no puede obtener atomicidad sin usar pg_dump o un sistema de archivos de instantánea.

Mi instancia de postgres está en zfs, la cual tomo instantáneas ocasionalmente. Es aproximadamente instantáneo y consistente.


Quiero hacer algo similar, agregar los cambios de mi base de datos a mi sistema de control de versiones.

Voy a seguir las ideas en esta publicación de Vladimir Khorikov "Mejores prácticas de versionamiento de bases de datos" . En resumen lo haré

  • almacene tanto su esquema como los datos de referencia en un sistema de control de origen.
  • Para cada modificación, crearemos un script SQL separado con los cambios.

En caso de que ayude!


Recomendaría neXtep para la versión que controla la base de datos, ya que tiene un buen conjunto de documentación y foros que explican cómo instalar y los errores encontrados. Lo he probado para postgreSQL 9.1 y 9.3, pude hacerlo funcionar para 9.1 pero para 9.3 no parece funcionar.


Solíamos ejecutar un sitio web social, en una configuración estándar de LAMP. Teníamos un servidor en vivo, un servidor de prueba y un servidor de desarrollo, así como las máquinas de los desarrolladores locales. Todos fueron gestionados utilizando GIT.

En cada máquina, teníamos los archivos PHP, pero también el servicio MySQL, y una carpeta con imágenes que los usuarios cargarían. El servidor de Live creció hasta tener unos 100K (!) Usuarios recurrentes, el volcado era de aproximadamente 2GB (!), La carpeta de imágenes tenía unos 50GB (!). Cuando me fui, nuestro servidor estaba llegando al límite de su CPU, Ram y, sobre todo, de los límites de conexión de red concurrentes (incluso compilamos nuestra propia versión del controlador de la tarjeta de red para maximizar el ''lol'' del servidor). No podríamos ( ni debes asumir con tu sitio web ) poner 2GB de datos y 50GB de imágenes en GIT.

Para administrar todo esto bajo GIT fácilmente, ignoraríamos las carpetas binarias (las carpetas que contienen las Imágenes) insertando estas rutas de carpetas en .gitignore. También teníamos una carpeta llamada SQL fuera de la ruta de acceso de documentos de Apache. En esa carpeta SQL, pondríamos nuestros archivos SQL de los desarrolladores en numeraciones incrementales (001.florianm.sql, 001.johns.sql, 002.florianm.sql, etc.). Estos archivos SQL fueron gestionados por GIT también. El primer archivo sql contendría un gran conjunto de esquemas de base de datos. No agregamos datos de usuario en GIT (por ejemplo, los registros de la tabla de usuarios o la tabla de comentarios), pero los datos como configuraciones o topología u otros datos específicos del sitio se mantuvieron en los archivos de SQL (y, por lo tanto, por GIT). Principalmente, son los desarrolladores (que conocen mejor el código) los que determinan qué y qué no mantiene GIT con respecto al esquema y los datos de SQL.

Cuando llegó a una versión, el administrador inicia sesión en el servidor de desarrollo, fusiona la rama en vivo con todos los desarrolladores y las ramas necesarias en la máquina de desarrollo en una rama de actualización, y la envía al servidor de prueba. En el servidor de prueba, comprueba si el proceso de actualización para el servidor de Live sigue siendo válido y, en una sucesión rápida, señala todo el tráfico de Apache a un sitio de marcador de posición, crea un volcado de base de datos, señala el directorio de trabajo de "en vivo" a "actualización" '', ejecuta todos los nuevos archivos sql en mysql, y vuelve a enviar el tráfico al sitio correcto. Cuando todas las partes interesadas estuvieron de acuerdo después de revisar el servidor de prueba, el Administrador hizo lo mismo desde el servidor de Prueba al servidor de Live. Luego, fusiona la rama en vivo en el servidor de producción, a la rama maestra en todos los servidores, y rebasó todas las ramas en vivo. Los desarrolladores se encargaron de reestructurar sus sucursales, pero en general saben lo que están haciendo.

Si hubo problemas en el servidor de prueba, por ejemplo. las fusiones tuvieron demasiados conflictos, luego se revirtió el código (apuntando la rama de trabajo a ''vivo'') y los archivos SQL nunca se ejecutaron. En el momento en que se ejecutaron los archivos SQL, esto se consideró como una acción no reversible en ese momento. Si los archivos SQL no funcionaban correctamente, entonces la base de datos se restauró utilizando el volcado (y los desarrolladores lo rechazaron, para proporcionar archivos SQL mal probados).

Hoy en día, mantenemos una carpeta de sql-up y sql-down, con nombres de archivos equivalentes, donde los desarrolladores tienen que probar que tanto los archivos de actualización de sql, pueden ser degradados por igual. En última instancia, esto podría ejecutarse con un script bash, pero es una buena idea si los ojos humanos siguieran monitoreando el proceso de actualización.

No es genial, pero es manejable. Espero que esto le dé una idea de un sitio de la vida real, práctico y de alta disponibilidad. Ya sea un poco desactualizado, pero aun así siguió.


Tome un volcado de base de datos, y controle la versión en su lugar. De esta manera es un archivo de texto plano.

Personalmente, le sugiero que mantenga un volcado de datos y un volcado de esquema. De esta manera, usar diff se vuelve bastante fácil ver lo que cambió en el esquema de una revisión a otra.

Si está realizando grandes cambios, debe tener una base de datos secundaria en la que realice los cambios del nuevo esquema y no toque la antigua ya que, como dijo, está creando una rama.


Use algo como LiquiBase, esto le permite mantener el control de revisión de sus archivos Liquibase. puede etiquetar cambios solo para producción, y tener lb mantiene su base de datos actualizada para producción o desarrollo (o cualquier esquema que desee).


Use una herramienta como iBatis Migrations ( manual , video tutorial corto ) que le permite controlar las versiones de los cambios que realiza en una base de datos durante todo el ciclo de vida de un proyecto, en lugar de la propia base de datos.

Esto le permite aplicar selectivamente cambios individuales a diferentes entornos, mantener un registro de cambios en qué entornos, crear scripts para aplicar los cambios A a N, cambios de reversión, etc.