Próbuję utworzyć klucze obce w Laravel, ale kiedy migruję tabelę przy użyciu, artisan
wyświetlany jest następujący błąd:
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL
: alter table `priorities` add constraint priorities_user_id_foreign foreign
key (`user_id`) references `users` (`id`))
Mój kod migracji jest taki:
plik migracji priorytetów
public function up()
{
//
Schema::create('priorities', function($table) {
$table->increments('id', true);
$table->integer('user_id');
$table->foreign('user_id')->references('id')->on('users');
$table->string('priority_name');
$table->smallInteger('rank');
$table->text('class');
$table->timestamps('timecreated');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
Schema::drop('priorities');
}
plik migracji użytkowników
public function up()
{
//
Schema::table('users', function($table)
{
$table->create();
$table->increments('id');
$table->string('email');
$table->string('first_name');
$table->string('password');
$table->string('email_code');
$table->string('time_created');
$table->string('ip');
$table->string('confirmed');
$table->string('user_role');
$table->string('salt');
$table->string('last_login');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
Schemea::drop('users');
}
Wszelkie pomysły na to, co zrobiłem źle, chcę to teraz uzyskać, ponieważ mam wiele tabel, które muszę utworzyć, np. Użytkownicy, Klienci, Projekty, Zadania, Statusy, Priorytety, Typy, Zespoły. Idealnie chcę tworzyć tabele, które przechowują te dane z kluczy obcych, i..e clients_project
i project_tasks
etc.
Mam nadzieję, że ktoś pomoże mi zacząć.
Schema::table
pomogło dodawanie bez znaku, oprócz separacji do metody! Dzięki!$table->unsignedBigInteger('user_id')
jeśli twój user.id tobigIncrements
Pytanie już zostało udzielone, ale mam nadzieję, że może to pomóc komuś innemu.
Ten błąd wystąpił dla mnie, ponieważ najpierw utworzyłem tabelę migracji z kluczem obcym, zanim klucz istniał jako klucz podstawowy w oryginalnej tabeli. Migracje są wykonywane w kolejności, w jakiej zostały utworzone, zgodnie z nazwą pliku wygenerowaną po uruchomieniu
migrate:make
. Np2014_05_10_165709_create_student_table.php
.Rozwiązaniem było zmienić nazwę pliku z kluczem obcym na wcześniejszy niż plik z kluczem podstawowym, zgodnie z zaleceniami tutaj: http://forumsarchive.laravel.io/viewtopic.php?id=10246
Myślę, że musiałem również dodać
$table->engine = 'InnoDB';
źródło
Laravel ^ 5.8
Przykład
Wyobraźmy sobie, że budujesz prostą aplikację opartą na rolach i musisz odwoływać się do user_id w tabeli PIVOT „role_user” .
2019_05_05_112458_create_users_table.php
2019_05_05_120634_create_role_user_pivot_table.php
Jak widać, skomentowany wiersz zgłosi wyjątek zapytania, ponieważ, jak wspomniano w uwagach dotyczących aktualizacji, kolumny klucza obcego muszą być tego samego typu , dlatego należy zmienić klucz prognostyczny (w tym przykładzie jest to identyfikator_użytkownika ) na bigInteger w tabeli rola_użytkownika lub zmień metodę bigIncrements na metodę inkrementacji w tabeli użytkowników i użyj komentowanego wiersza w tabeli przestawnej, to zależy od Ciebie.
Mam nadzieję, że udało mi się wyjaśnić ten problem.
źródło
Schema::table('goal_objective', function (Blueprint $table) { $table->bigInteger('job_title_id')->after('target')->unsigned()->nullable(); $table->foreign('job_title_id')->references('id')->on('job_titles')->onDelete('set null'); }
Zadziałało. Dziękuję Ci.W moim przypadku problem polegał na tym, że główna tabela zawierała już rekordy i zmuszałem nową kolumnę, aby nie miała wartości NULL. Więc dodanie -> nullable () do nowej kolumny załatwiło sprawę. W przykładzie pytania byłoby coś takiego:
$table->integer('user_id')->unsigned()->nullable();
lub:
$table->unsignedInteger('user_id')->nullable();
Mam nadzieję, że to komuś pomoże!
źródło
W moim przypadku problemem było ustawienie automatycznej generacji migracji dla
users
tabeliMusiałem więc zmienić typ kolumny
aby moja migracja z kluczem obcym działała.
To z laravelem
5.8.2
źródło
W moim przypadku problem polegał na tym, że podczas migracji należy zachować ostrożność podczas tworzenia migracji. Najpierw utwórz migrację potomną niż migrację podstawową. Ponieważ jeśli najpierw utworzysz migrację podstawową, która ma klucz obcy, poszuka tabeli podrzędnej, a nie będzie tabeli, która następnie wygeneruje wyjątek.
Ponadto:
Podczas tworzenia migracji na początku ma znacznik czasu. powiedzmy, że utworzyłeś kota migracji, więc będzie wyglądać
2015_08_19_075954_the_cats_time.php
i ma ten kodPo utworzeniu tabeli podstawowej tworzysz kolejną rasę migracji, która jest tabelą podrzędną, która ma własny znacznik czasu i daty utworzenia. Kod będzie wyglądał następująco:
Wygląda na to, że obie tabele są poprawne, ale po uruchomieniu migracji rzemieślnika php . Zgłasza wyjątek, ponieważ migracja najpierw utworzy tabelę bazową w bazie danych, ponieważ najpierw utworzyłeś tę migrację, a nasza tabela bazowa zawiera ograniczenie klucza obcego, które będzie szukało tabeli potomnej, a tabela potomna nie istnieje, co prawdopodobnie wyjątek..
Więc:
zrobione to zadziała
źródło
W moim przypadku po prostu zmieniam, że migracje zamówień są wykonywane ręcznie, więc użytkownicy tabeli są najpierw tworzeni.
W bazie danych folderów / migracje / nazwa pliku migracji ma następujący format: rok_miesiąc_dzien_godz. Godz. Tworzenia_XXXX_tabela.php
Wystarczy zmienić nazwę utwórz plik użytkownika, aby data utworzenia tabeli priorytetów tabeli została ustawiona później niż data użytkownika (wystarczy nawet sekunda później)
źródło
W laravel 5.8 tabela users_table używa
bigIncrements('id')
typu danych dla klucza podstawowego. Aby więc odwołać ograniczenie klucza obcego,user_id
kolumna musi byćunsignedBigInteger('user_id')
typu.źródło
Miałem ten sam problem podczas korzystania z Laravel 5.8. Po bliższym przyjrzeniu się dokumentom laravel, ponadto tutaj Migracje i duże zmiany . Rozwiązałem to, dodając klucze podstawowe „$ table-> bigIncrements ('id')” do każdej tabeli powiązanej z tabelą „users” i jej powiązaniami, w moim przypadku z tabelą „rola” . Na koniec miałem „$ table-> unsignedBigInteger” do kojarzenia ról z użytkownikami (Many-to-Many), to znaczy w tabeli „rola_użytkownika” .
źródło
Miałem ten problem z laravel 5.8 i naprawiłem ten kod, jak pokazano tutaj w dokumentacji Laravel , tam, gdzie kiedykolwiek dodałem klucz obcy.
potem pobiegłem
$ php artisan migrate:refresh
Ponieważ ta składnia jest dość szczegółowa, Laravel zapewnia dodatkowe, zwięzłe metody, które wykorzystują konwencję, aby zapewnić lepsze wrażenia programistyczne. Powyższy przykład można zapisać następująco:
źródło
Korzystanie z Laravel 5.3 miało ten sam problem.
Rozwiązaniem było użycie unsignedInteger zamiast liczby całkowitej ('name') -> unsigned () .
Więc to działało
Powodem tego było to, że podczas używania liczby całkowitej („nazwa”) -> bez znaku kolumna utworzona w tabeli miała długość 11, ale podczas używania liczby całkowitej bez znaku („nazwa”) kolumna miała długość 10.
Długość 10 to długość kluczy podstawowych, gdy używany jest Laravel, więc długość kolumn jest dopasowana.
źródło
Ten błąd wystąpił dla mnie, ponieważ - podczas gdy tabelę, którą próbowałem utworzyć, był InnoDB - tabela zagraniczna, z którą próbowałem ją powiązać, była tabelą MyISAM!
źródło
Nie możemy dodawać relacji, chyba że zostaną utworzone powiązane tabele. Laravel uruchamia migrację według daty plików migracji. Jeśli więc chcesz utworzyć relację z tabelą, która istnieje w drugim pliku migracji, nie powiedzie się.
Napotkałem ten sam problem, więc w końcu utworzyłem jeszcze jeden plik migracji, aby określić wszystkie relacje.
źródło
Pamiętaj: kiedy Laravel ustawia stół, używając
co jest standardem w większości migracji, spowoduje to ustawienie pola liczb całkowitych bez znaku. Dlatego podczas tworzenia odniesienia zagranicznego z innej tabeli do tego pola, upewnij się, że w tabeli odwołań ustawiłeś pole na UnsignedInteger, a nie (jakbym to było) UnsignedBigInteger.
Na przykład: w pliku migracji 2018_12_12_123456_create_users_table.php:
Następnie w pliku migracji 2018_12_12_18000000_create_permissions_table.php, który konfiguruje odniesienia zagraniczne dla użytkowników:
źródło
Powinieneś pisać w ten sposób
Pole klucza obcego powinno być niepodpisane , mam nadzieję, że to pomoże !!
źródło
Aby dodać ograniczenie klucza obcego w laravel, działało dla mnie:
Utwórz kolumnę jako klucz obcy w następujący sposób:
Dodanie linii ograniczenia bezpośrednio po (1) tj
źródło
wiem, że to stare pytanie, ale upewnij się, że jeśli pracujesz z referencjami, zdefiniowano odpowiedni silnik pomocniczy. ustaw silnik innodb dla obu tabel i ten sam typ danych dla kolumn referencyjnych
źródło
Wchodząc tutaj kilka lat po pierwotnym pytaniu, używając laravel 5.1, miałem ten sam błąd, ponieważ moje migracje były generowane komputerowo z tym samym kodem daty. Przejrzałem wszystkie zaproponowane rozwiązania, a następnie przebudowałem, aby znaleźć źródło błędu.
Uważam, że w kolejnych larakastach i podczas czytania tych postów poprawna odpowiedź jest podobna do odpowiedzi Vickies, z tym wyjątkiem, że nie trzeba dodawać osobnego wywołania schematu. Nie musisz ustawiać tabeli na Innodb, zakładam, że teraz robi to Laravel.
Migracje muszą po prostu być odpowiednio zsynchronizowane, co oznacza, że zmodyfikujesz kod daty w górę (później) w nazwie pliku dla tabel, w których potrzebujesz kluczy obcych. Alternatywnie lub dodatkowo, obniż kod danych dla tabel, które nie potrzebują kluczy obcych.
Zaletą modyfikacji kodu danych jest to, że kod migracji będzie łatwiejszy do odczytania i utrzymania.
Do tej pory mój kod działa, dostosowując kod czasowy w celu wypychania migracji, które wymagają kluczy obcych.
Mam jednak setki tabel, więc na samym końcu mam ostatnią tabelę tylko dla kluczy obcych. Tylko po to, żeby wszystko płynęło. Zakładam, że wciągnę je do odpowiedniego pliku i zmodyfikuję kod danych podczas ich testowania.
Przykład: plik 2016_01_18_999999_create_product_options_table. Ten wymaga utworzenia tabeli produktów. Spójrz na nazwy plików.
tabela produktów: najpierw należy przeprowadzić migrację. 2015_01_18_000000_create_products_table
I w końcu na samym końcu plik, którego tymczasowo używam do rozwiązywania problemów, który zrefakturuję, pisząc testy dla modeli, które nazwałem 9999_99_99_999999_create_foreign_keys.php. Te klucze są komentowane, gdy je wyciągnąłem, ale rozumiesz.
źródło
Tak prosty !!!
jeśli
'priorities'
tworzony jest pierwszy plik migracji, Laravel uruchamia się po raz pierwszy,'priorities'
gdy'users'
tabela nie istnieje.jak może dodać relację do tabeli, która nie istnieje!
Rozwiązanie: wyciągnij kody kluczy obcych z
'priorities'
tabeli. Twój plik migracji powinien wyglądać tak:i dodaj do nowego pliku migracji, tutaj jest jego nazwa
create_prioritiesForeignKey_table
i dodaj te kody:źródło
upewnij się, że twoja kolumna foreing jest zbyt szeroka
Mam na myśli, że twój klucz foreing (w drugiej tabeli) musi być tego samego typu, co twój klucz prognostyczny pontera (w pierwszej tabeli)
klucz główny wskaźnika musi być dodany bez znaku, pozwól mi pokazać:
w tabeli PIERWSZA migracja:
w tabeli migracji DRUGIEJ:
KOLEJNY PRZYKŁAD ZOBACZ RÓŻNICĘ
w tabeli PIERWSZA migracja:
w tabeli migracji DRUGIEJ:
ZOBACZ MYSQL TYPY ZAKRESÓW TABELI
źródło
Zauważyłem jedną rzecz, że jeśli tabele używają innego silnika niż ograniczenie klucza obcego nie działa.
Na przykład, jeśli jedna tabela używa:
I inne zastosowania
wygeneruje błąd:
Możesz to naprawić, dodając InnoDB na końcu tworzenia tabeli w następujący sposób:
źródło
W moim przypadku odwoływałem się do kolumny liczb całkowitych w
id
kolumnie ciągów znakówuser_id
. Zmieniłam:$table->string('user_id')
do:
$table->integer('user_id')->unsigned();
Mam nadzieję, że to komuś pomaga!
źródło
Istotą jest to, że metoda obca używa
ALTER_TABLE
do przekształcenia istniejącego pola w klucz obcy. Musisz więc zdefiniować typ tabeli przed zastosowaniem klucza obcego. Jednak nie musi to być osobneSchema::
połączenie. Możesz zrobić oba w ramach tworzenia, jak poniżej:Należy również pamiętać, że typ
user_id
jest ustawiony na unsigned, aby dopasować klucz obcy.źródło
Możesz bezpośrednio przekazać parametr boolowski w kolumnie liczb całkowitych, mówiąc, że powinien być bez znaku lub nie. W laravel 5.4 następujący kod rozwiązał mój problem.
W tym przypadku drugi parametr false oznacza, że nie powinien on automatycznie zwiększać, a trzeci parametr true oznacza, że powinien być niepodpisany. Możesz zachować ograniczenie klucza obcego podczas tej samej migracji lub oddzielić je. Działa na obu.
źródło
Jeśli żadne z powyższych rozwiązań nie działa dla początkujących, sprawdź, czy oba identyfikatory mają ten sam typ: oba są
integer
lub oba sąbigInteger
, ... Możesz mieć coś takiego:Główny stół (na przykład użytkownicy)
Stolik dziecięcy (na przykład priorytety)
To zapytanie nie powiodło się, ponieważ
users.id
jestBIG INTEGER
natomiastpriorities.user_id
toINTEGER
.Prawidłowe zapytanie w tym przypadku byłoby następujące:
źródło
W moim przypadku nie zadziałało, dopóki nie uruchomiłem polecenia
w ten sposób możesz zostawić klucze obce wewnątrz schematu tworzenia
źródło
Może to być również Twoja kolejność migracji tworzenia. Jeśli najpierw utworzysz tabelę priorytetów, a następnie tabelę użytkowników, będzie to nieprawidłowe. Z powodu pierwszej migracji poszukuję tabeli użytkowników. Musisz więc zmienić kolejność migracji
informator
źródło
Dla mnie kolumna tabeli, do której odwoływała się moja tabela potomna, nie była indeksowana.
Zignoruj straszne nazewnictwo, pochodzi z innego strasznie zaprojektowanego systemu.
źródło
Czasami ten błąd może wystąpić z powodu sekwencji migracji.
Podobnie jak Użytkownicy i Zamówienie to dwie tabele
Tabela zamówień ma klucz foriegn użytkowników (podczas migracji, jeśli migracja tabeli zamówień najpierw spowoduje problem, ponieważ nie ma użytkowników pasujących do klucza obcego)
Rozwiązanie: Wystarczy umieścić tabelę aktualizacji zamówienia pod użytkownikami w celu aktualizacji
Przykład: w moim przypadku tabele edukacji i uczelni Tabela edukacji
Na Uniwersytecie
źródło
Jednej rzeczy, której moim zdaniem brakuje w odpowiedziach tutaj, i proszę mnie poprawić, jeśli się mylę, ale klucze obce muszą być indeksowane w tabeli przestawnej. Wydaje się, że tak jest przynajmniej w mysql.
źródło