Data-fixtures: Truncar la tabla con claves externas falla

Creado en 12 jun. 2011  ·  25Comentarios  ·  Fuente: doctrine/data-fixtures

Cuando llamo al comando CLI de Symfony:

php app/console doctrine:fixtures:load

yo obtengo

[PDOException] 

SQLSTATE[42000]: Syntax error or access violation: 1701 Cannot truncate a table referenced in a foreign key constraint (symfony.param_product, CONSTRAINT param_product_ibfk_1 FOREIGN KEY (param_val_id) REFERENCES symfony.param_value (id))

La tabla symfony.param_product se crea mediante la anotación @ORM \ JoinTable (con @ORM \ ManyToMany). Estoy usando MySQL

Esto funcionó bien antes de este cambio: 91ff6ebbb781441c60782d90a4dd95482eeedf35

Pensé que podría ser un error de mi lado (por ejemplo, no hay opciones onDelete) pero todo lo que intenté falló.

Por lo que supe, por ejemplo, de http://forums.asp.net/t/1283840.aspx/1?How+can+I+truncate+the+table+which+have+foreign+key+

 ON DELETE CASCADE is true only for deleting records and not for truncating tables.

 You have to drop the foreign key constraint from Child Table that references the Master Table to be truncated, then after only you are able to truncate the Master Table. 

Entonces me parece que la única solución es usar DELETE o soltar primero las claves extranjeras.

¿Podemos revertir el cambio 91ff6ebbb781441c60782d90a4dd95482eeedf35 para solucionar este problema? @beberlei?

Comentario más útil

Aquí hay un truco rápido y sucio para que funcione con MySQL 5.5

diff --git a/lib/Doctrine/Common/DataFixtures/Purger/ORMPurger.php b/lib/Doctrine/Common/DataFixtures/Purger/ORMPurger.php
index a580c1f..ff758c1 100644
--- a/lib/Doctrine/Common/DataFixtures/Purger/ORMPurger.php
+++ b/lib/Doctrine/Common/DataFixtures/Purger/ORMPurger.php
@@ -82,10 +82,12 @@ class ORMPurger implements PurgerInterface
             $orderedTables[] = $class->getTableName();
         }

+       $this->em->getConnection()->executeUpdate("SET foreign_key_checks = 0;");
         $platform = $this->em->getConnection()->getDatabasePlatform();
         foreach($orderedTables as $tbl) {
             $this->em->getConnection()->executeUpdate($platform->getTruncateTableSQL($tbl, true));
         }
+       $this->em->getConnection()->executeUpdate("SET foreign_key_checks = 1;");
     }

     private function getCommitOrder(EntityManager $em, array $classes)

Todos 25 comentarios

El problema con el uso de DELETE es que no restablece el valor de incremento automático

Ok, pero el problema con TRUNCATE es que el comando doctrine: fixtures : load simplemente NO funciona.

Si es realmente necesario, siempre se puede iniciar el incremento automático desde 1, por ejemplo, soltando y volviendo a crear tablas, ¿verdad?

Sí, yo también tengo este problema. Volviendo a 91ff6ebbb781441c60782d90a4dd95482eeedf35 por ahora.

+1 para revertir 91ff6ebbb781441c60782d90a4dd95482eeedf35

¿Por qué no agregar simplemente 'CASCADE' al TRUNCATE? $ plataforma-> getTruncateTableSQL ($ tbl) tiene un segundo parámetro que devolvería algo como 'TRUNCATE table CASCADE' (al menos para postgres lo hace) y con eso funciona.

¿Qué tal agregar una solicitud de extracción? Entonces puedo fusionarlo.

@leahaense

El problema persiste al usar MySQL (incluso después de 4a8464ef83093de2378cef2770e13da7e4858ffc).

En ese caso, ¿sus claves externas son bidireccionales o algo así?

@beberlei sí, eso creo. No estoy 100% seguro, ya que Doctrine genera SQL a partir de anotaciones de uno a muchos / de muchos a muchos (que sí son bidireccionales).

¿Alguien más tiene este problema en MySQL? O solo soy yo?

¿Puedes hacer Foreign_key_checks = 0 antes de TRUNCATE?

http://bugs.mysql.com/bug.php?id=58788

También me estoy ocupando de este problema

He tenido exactamente el mismo problema con mi socio, esto sucede en MySQL 5.5, mientras que 5.1 está bien para truncar tablas con claves externas. Revertir a DELETE no sería una solución elegante como se indicó anteriormente si las teclas auto_increment no se restablecen.

Sería bueno si pudiera venir una solución como Foreign_key_checks = 0 para mysql 5.5

http://bugs.mysql.com/bug.php?id=54678

Aquí hay un truco rápido y sucio para que funcione con MySQL 5.5

diff --git a/lib/Doctrine/Common/DataFixtures/Purger/ORMPurger.php b/lib/Doctrine/Common/DataFixtures/Purger/ORMPurger.php
index a580c1f..ff758c1 100644
--- a/lib/Doctrine/Common/DataFixtures/Purger/ORMPurger.php
+++ b/lib/Doctrine/Common/DataFixtures/Purger/ORMPurger.php
@@ -82,10 +82,12 @@ class ORMPurger implements PurgerInterface
             $orderedTables[] = $class->getTableName();
         }

+       $this->em->getConnection()->executeUpdate("SET foreign_key_checks = 0;");
         $platform = $this->em->getConnection()->getDatabasePlatform();
         foreach($orderedTables as $tbl) {
             $this->em->getConnection()->executeUpdate($platform->getTruncateTableSQL($tbl, true));
         }
+       $this->em->getConnection()->executeUpdate("SET foreign_key_checks = 1;");
     }

     private function getCommitOrder(EntityManager $em, array $classes)

La solución anterior funciona muy bien para mí. ¿Alguna idea de cuándo se podría introducir una solución en el repositorio para no tener que cambiarla manualmente todo el tiempo?

También tuve que agregar esta solución para usar el paquete.

Lo anterior me lo arregló (por lo que puedo decir, todavía estoy aprendiendo Doctrine / Symfony2)

Hice los cambios foreign_key_checks en MySqlPlatform en el proyecto DBAL solo unos minutos después de que @mdarse envió su solicitud de extracción:

https://github.com/doctrine/dbal/pull/42

El mismo problema en mi máquina con MySQL 5.5.9, sin embargo, el truco de dogbrain ayudó.

¿Podemos integrar esta solución, por favor? De lo contrario, todos siempre tienen que agregarlo manualmente para que funcione.

No es una "solución", es un truco. No fusionaré un truco.

OK bastante justo. Sin embargo, es un truco que permite que los accesorios funcionen y sería bueno si lo hicieran;)
Si esto no se puede fusionar, ¿existe una solución? De lo contrario, hay un error que hace que este paquete sea inutilizable para muchas personas (sin piratear manualmente su código cada vez que se realiza una actualización).

@beberlei?

¿Podemos revertir el cambio 91ff6eb para solucionar este problema?

De esta forma no será un truco. Se sugirió en el primer artículo de este número.

No estoy seguro de hacerlo bien, pero tengo el mismo problema. No puedo averiguar qué versión estoy usando, la he descargado con composer con

"require": {
    "doctrine/doctrine-fixtures-bundle": "dev-master"
},

De todos modos, para obtener un reinicio de índice, necesito ejecutar " doctrine: schema : drop --force" y luego " doctrine: schema : update --force" antes de recargar. De lo contrario, tengo el mismo error. ¿Alguien puede decirme qué estoy haciendo mal?
Gracias por adelantado.

Tengo el mismo problema al ejecutar la última versión de doctrine fixtures y Mysql 5.5. El "truco" funcionó, pero esa no es una solución portátil. Tengo que eliminar el esquema y volver a crearlo cada vez.

Hágase un favor y cree un script dentro de la carpeta Symfony, como load_fixtures :

bin/console doc:sc:drop --force
bin/console doc:sc:cr
bin/console doc:fix:lo --no-interaction

Ejecute chmod 755 load_fixtures y luego ./load_fixtures.

¿Fue útil esta página
0 / 5 - 0 calificaciones