Error con doctrine:fixtures:load --purge-with-truncate y foreign key

533 views
Skip to first unread message

eduardobape

unread,
Feb 4, 2013, 3:58:17 PM2/4/13
to symfo...@googlegroups.com
Hola a todos.
No sé si alguno de vosotros ha leído el libro de Javier Eguiluz "Desarrollo web ágil con Symfony2" y ha desarrollado la aplicación del libro Cupon.

El caso es que, en el capítulo 5 de dicho libro, se explica el comando "php app/console doctrine:fixtures:load" para cargar datos iniciales en las tablas de la aplicación.
La aplicación tiene varias tablas, y entre ellas, una llamada Oferta y otra Venta. La tabla Venta tiene una foreign key a la clave primaria de la tabla Oferta (id).

He creado mi primer archivo de datos manualmente llamado "Ciudades.php" para inicializar la tabla Ciudades. Esta tabla tiene un campo llamado id que es auto-incremental.
Al ejecutar el comando "php app/console doctrine:fixtures:load" por primera vez, todo sale bien. La tabla Ciudades se llena con los datos indicados en el archivo de datos "Ciudades.php".
Después, quise probar el comando "php app/console doctrine:fixtures:load --purge-with-truncate" para comprobar si el campo id de la tabla Ciudades se reinicializaba a 1.
Obtuve el siguiente error:

[Doctrine\DBAL\DBALException]
An exception occurred while executing 'TRUNCATE Oferta':

SQLSTATE[42000]: Syntax error or access violation: 1701 Cannot truncate a table referenced in a foreign key constra
int (cupon.venta, CONSTRAINT FK_4E26C151FAFBF624 FOREIGN KEY (oferta_id) REFERENCEScupon.oferta (id)
)

[PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1701 Cannot truncate a table referenced in a foreign key constra
int (cupon.venta, CONSTRAINT FK_4E26C151FAFBF624 FOREIGN KEY (oferta_id) REFERENCEScupon.oferta (id)
)

Supongo que este error proviene de que el comando TRUNCATE de MySQL no se puede ejecutar si se quiere truncar una tabla cuya clave primaria está referenciada por las claves foráneas de otras tablas.
En mi caso, la clave primaria id de la tabla Oferta está referenciada por la clave foránea de la tabla Venta (oferta_id).
En el momento de ejecutar el comando las tablas Oferta y Venta están vacías.

He leído que para que esto se pueda hacer en MySQL hay que desactivar la restricción de claves foráneas (SET foreign_key_checks = 0), luego ejecutar el comando TRUNCATE , y al terminar de ejecutarse activar de nuevo la restricción de claves foráneas (SET foreign_key_checks = 1).

La cuestión es que no sé qué hacer para solucionarlo en Symfony 2.1.
¿Alguien más ha tenido este problema y tiene alguna solución?.
Gracias.

Eloy González Andueza

unread,
Feb 4, 2013, 4:07:45 PM2/4/13
to symfo...@googlegroups.com

Hola, a mí me pasó lo mismo, lo solucioné borrando las tablas y volviendo a generar las tablas y cargando los datos

--
--
Has recibido este mensaje porque estás suscrito al grupo "symfony-es" de Google Groups.
Para publicar en este grupo, envía un email a symfo...@googlegroups.com
Para darte de baja, envía un email a symfony-es+...@googlegroups.com
El resto de opciones puedes encontrarlas en http://groups.google.com/group/symfony-es?hl=es
 
---
Has recibido este mensaje porque estás suscrito al grupo "symfony-es" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus correos electrónicos, envía un correo electrónico a symfony-es+...@googlegroups.com.
Para obtener más opciones, visita https://groups.google.com/groups/opt_out.
 
 
Message has been deleted

eduardobape

unread,
Feb 5, 2013, 8:07:39 AM2/5/13
to symfo...@googlegroups.com
Gracias por tu respuesta Pepe. Efectivamente tu solución funciona.
Aun así, no veo porque el comando "php app/console doctrine:fixtures:load --purge-with-truncate" no es capaz de desactivar la restricción de claves foráneas y volver a activarla cuando termine.
Entonces, este comando sólo sirve para los datafixtures que no tratan con foreign keys. Se me hace difícil imaginarme una base de datos cuyas tablas no tengan claves foráneas.

Jakala

unread,
Feb 25, 2013, 7:15:44 AM2/25/13
to symfo...@googlegroups.com
Buenas, Eduardobape:

a mi me ocurre lo mismo, pero he visto un detalle que no se si lo estais evaluando.
El entorno en el que he trabajado hasta ahora es un ubuntu 12.04, y la versión de mysql que viene por defecto es una 5.5. En este caso, la creacion de los fixtures con el --purge-with-truncate da error en el caso de las claves foraneas.

sin embargo, en un entorno debian 6.0, que por defecto en los repositorios viene la version mysql 5.1, la ejecucion del --purge-with-truncate funciona sin problemas.

Coincide esta observación con tu caso? Y en caso de Pepe, tambien teneis la version 5.5?

Jakala

unread,
Feb 25, 2013, 7:17:19 AM2/25/13
to symfo...@googlegroups.com
Perdón, se me olvidó decir que hice un upgrade con el repositorio de dotdeb (para instalar la version 5.5 de mysql) y lanzar el fixtures con el --purge-with-truncate tambien da error (como el caso del ubuntu).

Personalmente creo que va por algo de la version de la bbdd, que opinais?

Eduardo

unread,
Feb 25, 2013, 11:35:31 AM2/25/13
to symfo...@googlegroups.com
Jakala, en mi caso, cuando obtuve el error estaba trabajando con MySQL 5.5.
Yo entiendo que no se pueda utilizar TRUNCATE en MySQL cuando la ÚNICA tabla a truncar está referenciada por otra tabla para no romper la integridad referencial.
Pero en el caso del comando doctrine:fixtures:load --purge-with-truncate, no estoy truncando una sola tabla. Como dije en un mensaje anterior, creo que no entiendo bien lo que hace internamente este comando. Lo que me imagino que hace es borrar TODAS las tablas de la base de datos, crear de nuevo el esquema y las tablas de la BD, y poblarlas de nuevo con los datos de los archivos de datos o fixtures.
¿Qué problema puede haber con la integridad referencial si el comando borra todas las tablas y las vuelve a crear de nuevo, para poblarlas de datos en un paso posterior?.


2013/2/25 Jakala <jaka...@gmail.com>
Perdón, se me olvidó decir que hice un upgrade con el repositorio de dotdeb (para instalar la version 5.5 de mysql) y lanzar el fixtures con el --purge-with-truncate tambien da error (como el caso del ubuntu).

Personalmente creo que va por algo de la version de la bbdd, que opinais?

--
--
Has recibido este mensaje porque estás suscrito al grupo "symfony-es" de Google Groups.
Para publicar en este grupo, envía un email a symfo...@googlegroups.com
Para darte de baja, envía un email a symfony-es+...@googlegroups.com
El resto de opciones puedes encontrarlas en http://groups.google.com/group/symfony-es?hl=es
 
---

Jakala

unread,
Feb 25, 2013, 12:52:52 PM2/25/13
to symfo...@googlegroups.com
Buenas:

por lo que entiendo despues de haber leido en el enlace http://dev.mysql.com/doc/refman/5.0/es/truncate.html , lo que se esta haciendo es un truncate TABLA A TABLA. No borras la bbdd completa y la recreas de nuevo (que es lo que hace la gente) sino que se van "truncando" tabla a tabla. 

En lo que se refiere al comando, es el LoadDataFixturesDoctrineCommand, y lo que hace es utilizar dos objetos:
ORMExecutor, que basicamente ejecuta las insercciones de los fixtures
ORMPurger, que es el encargado del famoso TRUNCATE. Si no se pone el parametro --purge-with-truncate, ejecuta un DELETE, sino, ejecuta el TRUNCATE sobre la tabla (ya que estas instrucciones van dentro de un bucle por cada tabla del schema).

En mi caso, de momento, he hecho un "copia-pega" de este comando, y le he añadido al ORMPurger la famosa instruccion:

        $this->em->getConnection()->executeQuery("SET foreign_key_checks = 0; ");

eso antes del bucle, y despues, la de valor = 1.

Pero aunque esto corrige el problema, seguimos con el tema de que funciona correctamente con mysql 5.1 y no con mysql 5.5

Jakala

unread,
Feb 25, 2013, 12:56:27 PM2/25/13
to symfo...@googlegroups.com
Por cierto, se me olvido decirlo: puedes ver lo que ejecuta el comando en el log que tienes en app/logs/dev.log (o prod.log, el que utilices de tu entorno). Ahi puedes ver que se ejecuta el truncate tabla a tabla (y no todo junto, como podriamos suponer inicialmente que "borraba" todas las tablas).

Eduardo

unread,
Feb 25, 2013, 9:13:00 PM2/25/13
to symfo...@googlegroups.com
Muy buena explicación. Gracias.


2013/2/25 Jakala <jaka...@gmail.com>
Por cierto, se me olvido decirlo: puedes ver lo que ejecuta el comando en el log que tienes en app/logs/dev.log (o prod.log, el que utilices de tu entorno). Ahi puedes ver que se ejecuta el truncate tabla a tabla (y no todo junto, como podriamos suponer inicialmente que "borraba" todas las tablas).

--
--
Has recibido este mensaje porque estás suscrito al grupo "symfony-es" de Google Groups.
Para publicar en este grupo, envía un email a symfo...@googlegroups.com
Para darte de baja, envía un email a symfony-es+...@googlegroups.com
El resto de opciones puedes encontrarlas en http://groups.google.com/group/symfony-es?hl=es
 
---
Reply all
Reply to author
Forward
0 new messages