Nota:
Antes que nada, evitar el uso de software que modifiquen las relaciones foreignKeys. Suelen cambiarle el nombre y esto provocará que al intentar realizar una migración probablemente falle.
Primero vamos a asignarle una base de datos a los entornos que hemos definido.Para ello necesitamos un usuario del motor con los privilegios necesarios para crear/eliminar una DB o la de root, lo cual no es recomendable.
./symfony configure:database "mysql:host=localhost;dbname=test" test testpass
./symfony configure:database "mysql:host=localhost;dbname=dev" dev devpass
Ahora podemos crear nuestra DB para el proyecto
./symfony doctrine:build-db --env=test
o destruirla... (muuaaajajaja)
./symfony doctrine:drop-db --env=test
Bien. Vamos a definir en nuestro esquema User con una propiedad name. Bastante simple para empezar.
schema.yml
User:
columns:
name:
type: string(255)
Aquí vamos a salir del camino del libro y hacer un poco de travesía. Directamente vamos a "versionar" nuestro esquema y así poder cambiar de versiones de nuestro esquema de base de datos.
El primer paso es generar los scripts de migración a partir del modelo actual.
./symfony doctrine:generate-migrations-model
Esto generará una serie de scripts en lib/migration/doctrine uno por cada definición en el esquema. En este punto no debería haber problemas con estos scripts pero conviene mirarlos para ver que va hacer.
Vamos a probar los scripts, es conveniente probarlo en algún otro entorno, por si falla, vió!
./symfony doctrine:migrate --env=test
Vas a ver un mensaje diciendo que se cambia de la versión 0 a la X, siendo X la cantidad de archivos que genero. No debemos olvidar aplicar los cambios en el entorno que estemos trabajando y por nada en el mundo generar las clases asociadas al esquema.
./symfony doctrine:migrate --env=dev
./symfony doctrine:build --all-classes
Esto generará las clases del modelo, forms y filters asociados al esquema. Genial, no ?
Es un buen momento hacer un commit de svn. agregamos el schema.yml y las carpetas en lib, model, form, filter y migration. Conviene llevar al día cada cambio, si hay algún problema podemos volver a una versión anterior.
Con el modelo actualizado, podemos hacer cambios nuevamente en el esquema. agregando Grupo.
schema.yml
User:
columns:
name:
type: string
group_id:
type: integer
notnull: true
relations:
Group:
local : group_id
foreign: id
Group:
columns:
name:
type: string
De esta forma definimos un Group y la relación One-Many de los User.
Ahora hacemos un diff entre nuestros modelos y el esquema.
./symfony doctrine:generate-migrations-diff.
Esto generará un (o varios) archivo en lib/migration. Este incluirá los cambios que se realizarán en la DB. Generará un archivo para agregar, quietar o modificar campos o tablas, y otro para las relaciones (foreign keys) dependiendo del tipo de relación.
Prestar mucha atención con esto, no queremos que borre una tabla y la volver a generarla, sino cambios mínimos o creación de nuevas tablas.
Es el momento de migrar nuevamente, puede pasar sin problema., o un super mensaje en rojo diciendo porque falló. Casi siempre el mensaje en rojo no se entiende, jeje pero bueno.
./symfony doctrine:migrate --env=test
En caso de error, deberemos identificar en que paso. Los errores mas comunes que me sucedieron en las relaciones. El campo local y foreign deben ser de igual tipo, largo y si es nulo.
Recordemos que en caso de necesitar empezar de nuevo podemos usar drop-db y build-db en el entorno test. También podemos ir migrando de a una versión a la vez incluyendo el número de versión. Si estamos en una versión superior, migrará hasta llegar a la versión 4 y de ser inferior ejecutara los scripts para llegar al mismo número.
./symfony doctrine:migrate --env=test 4
Una vez que estemos seguros que la migración funciona correctamente, deberíamos actualizar las clases:
./symfony doctrine:build --all-classes
Es tiempo de hacer un nuevo commit con los esquemas y modelos modificados y no olvides incluir los nuevos modelos y los archivos de migración.
Posteriormente migramos la db del entorno de desarrollo.
./symfony doctrine:migrate --env=dev
A Tener en cuenta:
En el caso de eliminar un campo, y este sea parte de una relación deberemos hacerlo en dos pasos:
- primero eliminar la relación del esquema, hacer el diff, migrar, build clases
- luego eliminar el campo deseado del esquema, diff, migrar y build clases.
Saludos.