SQL dump içe aktarırken çıkan “a foreign key constraint fails” hatasını düzeltme

İçe aktarma işleminiz yarı yolda Cannot add or update a child row: a foreign key constraint fails hatasıyla duruyor. Verilerde bir sorun yok — INSERT ifadelerinin sırası yanlış. İşte bunun neden olduğu ve düzeltmenin üç yolu.

Bir veritabanını dışa aktarıyorsunuz, onu yeni bir örneğe yüklemeye çalışıyorsunuz ve MySQL şu hatayı veriyor:

ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`app`.`orders`, CONSTRAINT `orders_user_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`))

Ya da PostgreSQL'de:

ERROR: insert or update on table "orders" violates foreign key constraint "orders_user_id_fkey"
DETAIL: Key (user_id)=(42) is not present in table "users".

Bu neden oluyor

Bir foreign key şunu söyler: “her orders.user_id mevcut bir users.id değerine işaret etmelidir.” Dump, orders kaydını users kayıtlarından önce eklediğinde, referans verilen üst satır henüz mevcut olmaz ve veritabanı satırı reddeder.

Çoğu dump aracı tabloları foreign key bağımlılık sırasına göre değil, alfabetik ya da oluşturulma sırasına göre yazar. Bu yüzden orders (alt tablo) sıklıkla users'tan (üst tablo) önce gelir ve içe aktarma bozulur.

Çözüm 1: INSERT'leri bağımlılığa göre yeniden sıralayın (doğru çözüm)

Temiz çözüm, her üst tabloyu alt tablolarından önce eklemektir. Bu, foreign key'leri bir bağımlılık grafiğine dönüştürmek ve tabloları topolojik sırayla yüklemek demektir: users → orders → order_items.

Bunu çok gigabaytlık bir dosyada elle yapmak eziyettir — her FOREIGN KEY'i CREATE TABLE ve ALTER TABLE ifadeleri arasında izlemeniz ve devasa INSERT bloklarını doğru sırayla kesip yapıştırmanız gerekir.

Çözüm 2: İçe aktarma sırasında foreign key kontrollerini devre dışı bırakın

Tam ve zaten tutarlı bir dump için, yükleme sırasında doğrulamayı güvenle atlayabilirsiniz. MySQL'de dosyayı şu şekilde sarmalayın:

-- MySQL
SET FOREIGN_KEY_CHECKS = 0;
-- ... tüm INSERT ifadeleriniz ...
SET FOREIGN_KEY_CHECKS = 1;

PostgreSQL'de kısıtlamaları bir işlem içinde erteleyin:

-- PostgreSQL
BEGIN;
SET CONSTRAINTS ALL DEFERRED;
-- ... tüm INSERT ifadeleriniz ...
COMMIT;

Gelecekteki yazma işlemlerinin doğrulanmaya devam etmesi için kontrolleri sonradan tekrar etkinleştirin. Bu işe yarar ama yalnızca sıralama sorununu maskeler — dump kısmiyse, yine de yetim satırlarla karşılaşabilirsiniz.

Çözüm 3: DumpCleaner ile ikisini de otomatik yapın

DumpCleaner dump'ı okur, her foreign key'i CREATE TABLE ve ALTER TABLE ifadelerinden çıkarır, bağımlılık grafiğini oluşturur ve içe aktarımı sorunsuz yapan temiz bir dosya dışa aktarır:

  1. .sql dump'ınızı DumpCleaner'a sürükleyin (MySQL, MariaDB, PostgreSQL, SQLite veya MS SQL).
  2. INSERT sırası → Bağımlılıklara göre (FK duyarlı) seçeneğini seçin. Üst tablolar topolojik sıralama sayesinde alt tablolardan önce otomatik olarak yerleştirilir.
  3. İsterseniz Foreign key kontrollerini devre dışı bırak seçeneğini işaretleyin — çıktıyı veritabanınıza uygun ifadeyle sarmalar.
  4. Dışa aktarın. Yeni dosyayı içe aktarın — kısıtlama hatası ortadan kalktı.

Hatta döngüsel foreign key'leri bile tespit eder ve imkânsız bir sıralama üretmek yerine sizi uyarır.

Elle INSERT ameliyatına son

DumpCleaner, her boyuttaki dosyada insert'leri foreign key bağımlılığına göre yeniden sıralar — akış tabanlı, sabit bellek kullanımıyla. Yerel macOS & iPadOS uygulaması, tek seferlik satın alma.

App Store'dan indir

Sıkça sorulan sorular

İçe aktarımda “a foreign key constraint fails” neden oluşur?

Bir alt satır, henüz eklenmemiş bir üst satıra referans verir; çünkü dump, INSERT'leri foreign key bağımlılığına göre değil, alfabetik olarak ya da oluşturulma zamanına göre sıralar.

İçe aktarma sırasında foreign key kontrollerini devre dışı bırakmak güvenli mi?

Tam ve tutarlı bir dump için evet. Yalnızca kaynak veritabanında zaten geçerli olan verilerin doğrulamasını atlarsınız. Sonrasında kontrolleri tekrar etkinleştirin.

Dosyayı elle düzenlemeden INSERT'leri nasıl yeniden sıralarım?

DumpCleaner foreign key'leri tespit eder, bir bağımlılık grafiği oluşturur ve INSERT'leri topolojik sırayla dışa aktarır — böylece üst tablolar her zaman alt tablolardan önce yüklenir.

Bu PostgreSQL için de çalışır mı?

Evet. DumpCleaner pg_dump çıktısını destekler ve hem SET CONSTRAINTS ALL DEFERRED ifadesini hem de bağımlılık sırasına göre insert'leri üretebilir.

Dump'ları FK derdi olmadan içe aktarın

Sürükleyin, bağımlılıklara göre yeniden sıralayın, dışa aktarın. DumpCleaner foreign key'leri hallederek içe aktarımınızın sorunsuz çalışmasını sağlar.

App Store'dan indir