Eksportuojate duomenų bazę, bandote ją įkelti į naują serverį, o MySQL išmeta:
Arba PostgreSQL atveju:
DETAIL: Key (user_id)=(42) is not present in table "users".
Kodėl taip nutinka
Išorinis raktas sako: „kiekvienas orders.user_id turi rodyti į egzistuojantį users.id.“ Kai išklotinė įterpia orders anksčiau nei users, nurodyta pirminė eilutė dar neegzistuoja, ir duomenų bazė atmeta eilutę.
Dauguma išklotinių įrankių lenteles rašo abėcėlės tvarka arba sukūrimo tvarka — bet ne pagal išorinių raktų priklausomybių tvarką. Todėl orders (antrinė) dažnai atsiduria prieš users (pirminę), ir importas nutrūksta.
1 sprendimas: pertvarkyti INSERT pagal priklausomybes (teisingas sprendimas)
Švarus sprendimas — kiekvieną pirminę lentelę įterpti prieš jos antrines lenteles. Tai reiškia išorinius raktus paversti priklausomybių grafu ir lenteles įkelti topologine tvarka: users → orders → order_items.
Daryti tai rankomis kelių gigabaitų faile — kančia: tenka atsekti kiekvieną FOREIGN KEY per CREATE TABLE ir ALTER TABLE sakinius bei iškirpti ir įklijuoti didžiulius INSERT blokus teisinga tvarka.
2 sprendimas: išjungti išorinių raktų tikrinimą importo metu
Jei išklotinė yra pilna ir jau nuosekli, tikrinimą galima saugiai praleisti įkėlimo metu. MySQL atveju apgaubkite failą:
-- MySQL SET FOREIGN_KEY_CHECKS = 0; -- ... visi jūsų INSERT sakiniai ... SET FOREIGN_KEY_CHECKS = 1;
PostgreSQL atveju atidėkite apribojimus tranzakcijos viduje:
-- PostgreSQL BEGIN; SET CONSTRAINTS ALL DEFERRED; -- ... visi jūsų INSERT sakiniai ... COMMIT;
Po to vėl įjunkite tikrinimą, kad būsimi įrašymai liktų patikrinti. Tai veikia, tačiau tik paslepia eiliškumo problemą — jei išklotinė yra dalinė, vis tiek galite likti su „našlaitėmis“ eilutėmis.
3 sprendimas: padaryti abu automatiškai su DumpCleaner
DumpCleaner perskaito išklotinę, iš CREATE TABLE ir ALTER TABLE ištraukia kiekvieną išorinį raktą, sudaro priklausomybių grafą ir eksportuoja švarų failą, kuris tiesiog importuojasi:
- Nutempkite savo
.sqlišklotinę į DumpCleaner (MySQL, MariaDB, PostgreSQL, SQLite ar MS SQL). - Pasirinkite INSERT tvarka → Pagal priklausomybes (atsižvelgiant į FK). Pirminės lentelės automatiškai išdėstomos prieš antrines, naudojant topologinį rūšiavimą.
- Norėdami, pažymėkite Išjungti išorinių raktų tikrinimą — tuomet išvestis apgaubiama teisingu jūsų duomenų bazės sakiniu.
- Eksportuokite. Importuokite naują failą — apribojimo klaidos nebėra.
Programa netgi aptinka ciklinius išorinius raktus ir įspėja jus, užuot sukūrusi neįmanomą tvarką.
Jokios daugiau rankinės INSERT „chirurgijos“
DumpCleaner pertvarko INSERT pagal išorinių raktų priklausomybes bet kokio dydžio failuose — srautiniu būdu, su pastoviu atminties naudojimu. Vietinė macOS ir iPadOS programa, vienkartinis pirkimas.
Atsisiųsti iš App StoreDažnai užduodami klausimai
Kodėl importuojant įvyksta „a foreign key constraint fails“?
Antrinė eilutė nurodo pirminę eilutę, kuri dar nebuvo įterpta, nes išklotinė INSERT sakinius išdėsto abėcėlės ar sukūrimo tvarka, o ne pagal išorinių raktų priklausomybes.
Ar saugu išjungti išorinių raktų tikrinimą importo metu?
Taip, jei išklotinė pilna ir nuosekli. Jūs tik praleidžiate duomenų, kurie šaltinio duomenų bazėje jau buvo teisingi, tikrinimą. Po to vėl įjunkite tikrinimą.
Kaip pertvarkyti INSERT nekeičiant failo rankomis?
DumpCleaner aptinka išorinius raktus, sudaro priklausomybių grafą ir eksportuoja INSERT topologine tvarka — kad pirminės lentelės visada įsikeltų prieš antrines.
Ar tai veikia ir su PostgreSQL?
Taip. DumpCleaner palaiko pg_dump išvestį ir gali sugeneruoti tiek SET CONSTRAINTS ALL DEFERRED, tiek pagal priklausomybes išdėstytus įterpimus.
Importuokite išklotines be FK galvos skausmo
Nutempkite, pertvarkykite pagal priklausomybes, eksportuokite. DumpCleaner sutvarko išorinius raktus, kad jūsų importas tiesiog veiktų.
Atsisiųsti iš App Store