Estoy trabajando en una aplicación de rieles con bastantes ramas git y muchas de ellas incluyen migraciones db. Intentamos tener cuidado, pero ocasionalmente algún código en el maestro solicita una columna que se eliminó / renombró en otra rama.
¿Cuál sería una buena solución para "emparejar" ramas git con estados DB?
¿Cuáles serían estos "estados" en realidad?
No podemos simplemente duplicar una base de datos si tiene unos pocos GB de tamaño.
¿Y qué debería pasar con las fusiones?
¿La solución se traduciría también en bases de datos noSQL?
Actualmente usamos MySQL, mongodb y redis
EDITAR: Parece que olvidé mencionar un punto muy importante, solo estoy interesado en el entorno de desarrollo pero con grandes bases de datos (unos pocos GB de tamaño).
fuente
Respuestas:
Cuando agrega una nueva migración en cualquier sucursal, ejecute
rake db:migrate
y confirme tanto la migración comodb/schema.rb
Si hace esto, en el desarrollo, podrá cambiar a otra rama que tenga un conjunto diferente de migraciones y simplemente ejecutar
rake db:schema:load
.Tenga en cuenta que esto recreará la base de datos completa y se perderán los datos existentes .
Probablemente solo desee ejecutar la producción desde una rama con la que tenga mucho cuidado, por lo que estos pasos no se aplican allí (solo se ejecuta
rake db:migrate
como de costumbre allí). Pero en el desarrollo, no debería ser un gran problema recrear la base de datos a partir del esquema, que es lorake db:schema:load
que hará.fuente
db/seeds.rb
No debería ser demasiado devastador destruir su base de datos de desarrollo si configura algunos datos iniciales razonables allí.db/seeds.rb
para ripopular los datos de db perdidosSi tiene una base de datos grande que no puede reproducir fácilmente, le recomiendo usar las herramientas de migración normales. Si desea un proceso simple, esto es lo que recomendaría:
rake db:rollback
) al estado anterior al punto de ramificación. Luego, después de cambiar de rama, corredb:migrate
. Esto es matemáticamente correcto y, siempre y cuando escribasdown
guiones, funcionará.fuente
rake db:schema:load
y,rake db:seed
como había dicho @noodl.Aquí hay un script que escribí para cambiar entre ramas que contienen diferentes migraciones:
https://gist.github.com/4076864
No resolverá todos los problemas que mencionó, pero dado un nombre de sucursal lo hará:
Me encuentro haciendo esto manualmente todo el tiempo en nuestro proyecto, así que pensé que sería bueno automatizar el proceso.
fuente
git checkout db/schema.rb
o quiso decirgit checkout -- db/schema.rb
? (es decir, con guiones dobles)db/schema.rb
. :)Base de datos separada para cada rama
Es la única forma de volar.
Actualización 16 de octubre de 2017
Volví a esto después de bastante tiempo e hice algunas mejoras:
bundle exec rake git:branch
.db:clone_from_branch
tarea tomaSOURCE_BRANCH
y unaTARGET_BRANCH
variable de entorno. Cuando lo usegit:branch
, usará automáticamente la rama actual comoSOURCE_BRANCH
.config/database.yml
Y para que sea más fácil para usted, así es como actualiza su
database.yml
archivo para determinar dinámicamente el nombre de la base de datos en función de la rama actual.lib/tasks/db.rake
Aquí hay una tarea de Rastrillo para clonar fácilmente su base de datos de una rama a otra. Esto toma una
SOURCE_BRANCH
y unaTARGET_BRANCH
variables de entorno. Basado en la tarea de @spalladino .lib/tasks/git.rake
Esta tarea creará una rama git fuera de la rama actual (maestra o de otra manera), échale un vistazo y clona la base de datos de la rama actual en la base de datos de la nueva rama. Es hábil AF.
Ahora, todo lo que necesitas hacer es correr
bundle exec git:branch
, ingresar el nuevo nombre de la sucursal y comenzar a matar zombies.fuente
¿Quizás debería tomar esto como una pista de que su base de datos de desarrollo es demasiado grande? Si puede usar db / seeds.rb y un conjunto de datos más pequeño para el desarrollo, entonces su problema puede resolverse fácilmente usando schema.rb y seeds.rb de la rama actual.
Eso supone que su pregunta se relaciona con el desarrollo; No puedo imaginar por qué necesitarías cambiar de sucursal regularmente en producción.
fuente
db/seeds.rb
, lo examinaré.Estaba luchando con el mismo problema. Aquí está mi solución:
Asegúrese de que tanto el schema.rb como todas las migraciones sean verificadas por todos los desarrolladores.
Debe haber una persona / máquina para implementaciones en producción. Llamemos a esta máquina como la máquina de fusión. Cuando los cambios se llevan a la máquina de fusión, la fusión automática para schema.rb fallará. Sin problemas. Simplemente reemplace el contenido con los contenidos anteriores de schema.rb (puede dejar una copia a un lado u obtenerla de github si la usa ...).
Aquí está el paso importante. Las migraciones de todos los desarrolladores ahora estarán disponibles en la carpeta db / migrate. Siga adelante y ejecute bundle exec rake db: migrate. Traerá la base de datos en la máquina de fusión a la par con todos los cambios. También regenerará schema.rb.
Comprometa y envíe los cambios a todos los repositorios (controles remotos e individuos, que también son controles remotos). ¡Deberías haber terminado!
fuente
Esto es lo que he hecho y no estoy seguro de haber cubierto todas las bases:
En desarrollo (usando postgresql):
Esto es mucho más rápido que las utilidades de rake en una base de datos con aproximadamente 50K registros.
Para la producción, mantenga la rama maestra como sacrosanta y todas las migraciones se registran, shema.rb se fusionó correctamente. Siga su procedimiento de actualización estándar.
fuente
Desea preservar un "entorno db" por rama. Mire el guión borroso / limpio para señalar diferentes instancias. Si se queda sin instancias de db, haga que el script genere una instancia temporal para que cuando cambie a una nueva rama, ya esté allí y solo necesite cambiar el nombre del script. Las actualizaciones de la base de datos deberían ejecutarse justo antes de ejecutar sus pruebas.
Espero que esto ayude.
fuente
Experimento totalmente la pita que tienes aquí. Mientras lo pienso, el verdadero problema es que todas las ramas no tienen el código para deshacer ciertas ramas. Estoy en el mundo de Django, así que no conozco tan bien. Estoy jugando con la idea de que las migraciones viven en su propio repositorio que no se ramifica (git-submodule, del que me enteré recientemente). De esa manera todas las ramas tienen todas las migraciones. La parte adhesiva es asegurarse de que cada rama esté restringida solo a las migraciones que les interesan. Hacer / hacer un seguimiento de eso manualmente sería una pita y propenso a errores. Pero ninguna de las herramientas de migración está diseñada para esto. Ese es el punto en el que estoy sin un camino a seguir.
fuente
Sugeriría una de dos opciones:
Opción 1
seeds.rb
. Una buena opción es crear sus datos de semillas a través de FactoryGirl / Fabrication gem. De esta manera, puede garantizar que los datos estén sincronizados con el código si suponemos que las fábricas se actualizan junto con la adición / eliminación de columnas.rake db:reset
, lo que efectivamente elimina / crea / inicializa la base de datos.opcion 2
Mantenga manualmente los estados de la base de datos ejecutando siempre
rake db:rollback
/rake db:migrate
antes / después de un pago de sucursal. La advertencia es que todas sus migraciones deben ser reversibles, de lo contrario esto no funcionará.fuente
En entorno de desarrollo:
Debería trabajar con
rake db:migrate:redo
para comprobar si su script es reversible, pero tenga en cuenta que siempre debe tener unaseed.rb
con la población de datos.Si trabaja con git, su seed.rb debe cambiarse con un cambio de migración y la ejecución del
db:migrate:redo
principio (cargue los datos para un nuevo desarrollo en otra máquina o nueva base de datos)Además de "cambio", con los métodos de arriba y abajo, su código siempre será escenarios de cobertura para el "cambio" en este momento y cuando comience desde cero.
fuente