Data-fixtures: Memotong tabel dengan kunci asing gagal

Dibuat pada 12 Jun 2011  ·  25Komentar  ·  Sumber: doctrine/data-fixtures

Ketika saya memanggil perintah symfony CLI:

php app/console doctrine:fixtures:load

saya mendapat

[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))

Tabel symfony.param_product dibuat dengan anotasi @ORM\JoinTable (dengan @ORM\ManyToMany). Saya menggunakan MySQL

Ini berfungsi dengan baik sebelum perubahan ini: 91ff6ebbb781441c60782d90a4dd95482eeedf35

Saya pikir itu mungkin bug di pihak saya (misalnya tidak ada opsi onDelete) tetapi semua yang saya coba gagal.

Sejauh yang saya pelajari misalnya dari 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. 

Jadi menurut saya satu-satunya solusi adalah menggunakan DELETE atau menjatuhkan kunci foregin terlebih dahulu.

Bisakah kita mengembalikan perubahan 91ff6ebbb781441c60782d90a4dd95482eeedf35 untuk memperbaiki masalah ini? @beberlei?

Komentar yang paling membantu

Berikut ini adalah peretasan kotor cepat untuk membuatnya berfungsi dengan 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)

Semua 25 komentar

Masalah dengan menggunakan DELETE adalah tidak mengatur ulang nilai kenaikan otomatis

Oke, tetapi masalah dengan TRUNCATE adalah bahwa perintah doktrin: perlengkapan : memuat TIDAK berfungsi.

Jika memang benar-benar dibutuhkan, memulai auto increment dari 1 selalu bisa dilakukan misalnya dengan menjatuhkan dan membuat ulang tabel, bukan?

Yap - saya juga punya masalah ini. Kembali ke 91ff6ebbb781441c60782d90a4dd95482eeedf35 untuk saat ini.

+1 untuk mengembalikan 91ff6ebbb781441c60782d90a4dd95482eeedf35

Mengapa tidak menambahkan 'CASCADE' ke TRUNCATE? $platform->getTruncateTableSQL($tbl) memiliki parameter kedua yang akan mengembalikan sesuatu seperti 'TRUNCATE table CASCADE' (setidaknya untuk postgres itu) dan dengan itu berfungsi.

Bagaimana kalau menambahkan permintaan tarik? Saya bisa menggabungkannya kalau begitu.

@leahaense

Masalah masih ada saat menggunakan MySQL (bahkan setelah 4a8464ef83093de2378cef2770e13da7e4858ffc).

Dalam hal ini kunci asing Anda adalah dua arah atau sesuatu?

@beberlei ya saya pikir begitu. Saya tidak 100% yakin karena SQL dihasilkan oleh Doctrine dari anotasi satu-ke-banyak/banyak-ke-banyak (yang ya adalah dua arah).

Adakah orang lain yang mengalami masalah ini di MySQL? Atau hanya aku?

Bisakah Anda melakukan foreign_key_checks=0 sebelum TRUNCATE ?

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

Saya juga memukul masalah ini

Saya telah mengalami masalah yang sama persis dengan pasangan saya, ini memang terjadi pada MySQL 5.5 sementara 5.1 baik-baik saja dengan memotong tabel dengan kunci asing. Kembali ke DELETE tidak akan menjadi solusi elegan seperti yang dinyatakan sebelumnya dengan kunci auto_increment tidak diatur ulang.

Akan lebih baik jika ada perbaikan seperti foreign_key_checks=0 untuk mysql 5.5

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

Berikut ini adalah peretasan kotor cepat untuk membuatnya berfungsi dengan 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)

Perbaikan di atas bekerja sangat baik untuk saya. Adakah ide ketika perbaikan dapat diperkenalkan ke repo jadi saya tidak perlu mengubahnya secara manual setiap saat?

Saya juga harus menambahkan perbaikan ini untuk menggunakan bundel.

Di atas memperbaikinya untuk saya (sejauh yang saya tahu, masih belajar Doctrine/Symfony2)

Saya membuat perubahan foreign_key_checks ke MySqlPlatform pada proyek DBAL itu sendiri hanya beberapa menit setelah @mdarse mengirimkan permintaan tariknya:

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

Masalah yang sama pada mesin saya dengan MySQL 5.5.9, namun peretasan dogbrain membantu.

Bisakah kami membuat perbaikan ini terintegrasi? Kalau tidak, setiap orang selalu harus menambahkannya secara manual untuk membuatnya berfungsi.

Ini bukan "memperbaiki" ini adalah peretasan. Saya tidak akan menggabungkan retasan.

OK cukup adil. Namun, ini adalah peretasan yang memungkinkan perlengkapan berfungsi dan akan lebih baik jika mereka melakukannya;)
Jika ini tidak dapat digabungkan, apakah ada perbaikan yang dapat dilakukan? Kalau tidak, ada bug yang membuat bundel ini tidak dapat digunakan oleh banyak orang (tanpa terus-menerus meretas kodenya secara manual setiap kali pembaruan dilakukan)

@beberlei?

Bisakah kita mengembalikan perubahan 91ff6eb untuk memperbaiki masalah ini?

Dengan cara ini, itu tidak akan menjadi peretasan. Itu disarankan di posting pertama dalam masalah ini.

Saya tidak yakin saya melakukannya dengan benar, namun saya memiliki masalah yang sama. Saya tidak tahu versi apa yang saya gunakan, saya telah mengunduh dengan komposer dengan

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

Bagaimanapun, untuk mendapatkan pengaturan ulang indeks, saya perlu menjalankan " doktrin: skema : jatuhkan -- force" dan kemudian " doktrin: skema : perbarui -- paksa" sebelum memuat ulang. Kalau tidak, saya memiliki kesalahan yang sama. Dapatkah seseorang tolong beri tahu saya apa yang saya lakukan salah?
Terima kasih sebelumnya.

Saya mengalami masalah yang sama saat menjalankan versi terbaru perlengkapan doktrin dan Mysql 5.5. "Peretasan" berhasil, tetapi itu bukan solusi portabel. Saya harus menghapus skema dan membuatnya kembali setiap saat.

Bantulah diri Anda sendiri dan buat skrip di dalam folder Symfony, seperti load_fixtures :

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

Jalankan chmod 755 load_fixtures lalu ./load_fixtures.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat