Ich versuche, Fremdschlüssel in Laravel zu erstellen, aber wenn ich meine Tabelle mit migriere artisan
, wird der folgende Fehler ausgegeben:
[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`))
Mein Migrationscode lautet wie folgt:
Migrationsdatei für Prioritäten
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');
}
Benutzer-Migrationsdatei
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');
}
Irgendwelche Ideen, was ich falsch gemacht habe, möchte ich sofort machen, da ich viele Tabellen habe, die ich erstellen muss, z. B. Benutzer, Kunden, Projekte, Aufgaben, Status, Prioritäten, Typen, Teams. Im Idealfall möchte ich Tabellen erstellen , die diese Daten mit dem Fremdschlüssel, i..e halten clients_project
und project_tasks
usw.
Hoffe, jemand kann mir helfen, loszulegen.
Schema::table
Methode hat geholfen! Vielen Dank!$table->unsignedBigInteger('user_id')
wenn Ihre user.id istbigIncrements
Die Frage wurde bereits beantwortet, aber ich hoffe, dies könnte jemand anderem helfen.
Dieser Fehler trat bei mir auf, weil ich zuerst die Migrationstabelle mit dem Fremdschlüssel erstellt habe, bevor der Schlüssel als Primärschlüssel in der ursprünglichen Tabelle vorhanden war. Migrationen werden in der Reihenfolge ausgeführt, in der sie erstellt wurden, wie durch den nach der Ausführung generierten Dateinamen angegeben
migrate:make
. ZB2014_05_10_165709_create_student_table.php
.Die Lösung bestand darin, die Datei mit dem Fremdschlüssel zu einem früheren Zeitpunkt als die Datei mit dem Primärschlüssel umzubenennen, wie hier empfohlen: http://forumsarchive.laravel.io/viewtopic.php?id=10246
Ich denke, ich musste auch hinzufügen
$table->engine = 'InnoDB';
quelle
Laravel ^ 5.8
Beispiel
Stellen Sie sich vor, Sie erstellen eine einfache rollenbasierte Anwendung und müssen in der PIVOT- Tabelle "role_user" auf user_id verweisen .
2019_05_05_112458_create_users_table.php
2019_05_05_120634_create_role_user_pivot_table.php
Wie Sie sehen können, löst die kommentierte Zeile eine Abfrageausnahme aus, da Fremdschlüsselspalten , wie in den Upgrade-Hinweisen erwähnt, vom gleichen Typ sein müssen. Daher müssen Sie entweder den Vorschlüssel (in diesem Beispiel user_id ) in ändern bigInteger in der Tabelle role_user oder ändern Sie die bigIncrements- Methode in die Inkrementierungsmethode in der Benutzertabelle und verwenden Sie die kommentierte Zeile in der Pivot-Tabelle. Es liegt an Ihnen.
Ich hoffe, ich konnte Ihnen dieses Problem klären.
quelle
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'); }
Es funktionierte. Danke dir.In meinem Fall bestand das Problem darin, dass die Haupttabelle bereits Datensätze enthielt und ich die neue Spalte zwang, nicht NULL zu sein. Das Hinzufügen von -> nullable () zur neuen Spalte hat also den Trick getan. Im Beispiel der Frage wäre so etwas:
$table->integer('user_id')->unsigned()->nullable();
oder:
$table->unsignedInteger('user_id')->nullable();
Hoffe das hilft jemandem!
quelle
In meinem Fall bestand das Problem darin, dass die automatisch generierte Migration für die
users
Tabelle festgelegt wurdeAlso musste ich den Spaltentyp ändern
damit meine Migration mit dem Fremdschlüssel funktioniert.
Dies mit Laravel
5.8.2
quelle
In meinem Fall bestand das Problem darin, dass das Migrations-Timing beim Erstellen von Migrationen vorsichtig sein sollte. Erstellen Sie zuerst die untergeordnete Migration als die Basismigration. Denn wenn Sie zuerst eine Basismigration erstellen, bei der Ihr Fremdschlüssel nach einer untergeordneten Tabelle sucht, gibt es keine Tabelle, die dann eine Ausnahme auslöst.
Außerdem:
Wenn Sie eine Migration erstellen, wird am Anfang ein Zeitstempel angezeigt. können sagen , dass Sie eine Migration erstellt haben , Katze , so dass es aussehen wird
2015_08_19_075954_the_cats_time.php
und es diesen Code hatUnd nachdem Sie die Basistabelle erstellt haben, erstellen Sie eine andere Migrationsrasse , die untergeordnete Tabelle, die einen eigenen Erstellungszeit- und Datumsstempel hat. Der Code sieht folgendermaßen aus:
es scheint, dass diese beiden Tabellen korrekt sind, aber wenn Sie PHP Artisan Migrate ausführen . Es wird eine Ausnahme ausgelöst, da durch die Migration zuerst die Basistabelle in Ihrer Datenbank erstellt wird, da Sie diese Migration zuerst erstellt haben und unsere Basistabelle eine Fremdschlüsseleinschränkung enthält, die nach einer untergeordneten Tabelle sucht und die untergeordnete Tabelle wahrscheinlich nicht vorhanden ist eine Ausnahme..
So:
fertig wird es funktionieren
quelle
In meinem Fall ändere ich nur die Reihenfolge, in der Migrationen manuell ausgeführt werden, sodass zuerst Tabellenbenutzer erstellt werden.
In der Ordnerdatenbank / migrations / Ihr Migrationsdateiname haben Sie das folgende Format: year_month_day_hhmmss_create_XXXX_table.php
Benennen Sie einfach die Benutzerdatei erstellen um, damit das Erstellungsdatum Ihrer Tabellenprioritätstabelle später als das Benutzerdatum festgelegt wird (sogar eine Sekunde später ist ausreichend).
quelle
In Laravel 5.8 verwendet die users_table den
bigIncrements('id')
Datentyp für den Primärschlüssel. Wenn Sie also auf eine Fremdschlüsseleinschränkung verweisen möchten, muss Ihreuser_id
Spalte vomunsignedBigInteger('user_id')
Typ sein.quelle
Ich hatte das gleiche Problem mit Laravel 5.8. Nachdem Sie sich die Laravel-Dokumente genauer angesehen haben, finden Sie hier auch Migrations & bigIncrements . Ich habe es gelöst, indem ich jeder einzelnen Tabelle, die sich auf die Tabelle "Benutzer" und ihre Zuordnungen bezieht, Primärschlüssel "$ table-> bigIncrements ('id')" hinzugefügt habe , in meinem Fall die Tabelle "Rolle" . Zuletzt hatte ich "$ table-> unsignedBigInteger" zum Zuordnen von Rollen zu Benutzern (Many-to-Many), dh Tabelle "role_user" .
quelle
Ich hatte dieses Problem mit Laravel 5.8 und habe diesen Code, wie hier in der Laravel-Dokumentation gezeigt , an der Stelle behoben , an der ich einen Fremdschlüssel hinzufüge.
dann rannte ich
$ php artisan migrate:refresh
Da diese Syntax ziemlich ausführlich ist, bietet Laravel zusätzliche, kürzere Methoden, die Konventionen verwenden, um eine bessere Entwicklererfahrung zu erzielen. Das obige Beispiel könnte folgendermaßen geschrieben werden:
quelle
Die Verwendung von Laravel 5.3 hatte das gleiche Problem.
Die Lösung bestand darin, unsignedInteger anstelle von integer ('name') -> unsigned () zu verwenden .
Das hat also funktioniert
Der Grund, warum dies funktioniert hat, ist die Tatsache, dass bei Verwendung von Integer ('Name') -> unsigned die in der Tabelle erstellte Spalte die Länge 11 hatte, bei Verwendung von unsigedInteger ('Name') die Spalte jedoch die Länge 10 hatte.
Länge 10 ist die Länge für Primärschlüssel, wenn Laravel verwendet wird, sodass die Spaltenlänge übereinstimmt.
quelle
Dieser Fehler trat bei mir auf, weil - während die Tabelle, die ich erstellen wollte, InnoDB war - die fremde Tabelle, auf die ich sie beziehen wollte, eine MyISAM-Tabelle war!
quelle
Wir können keine Beziehungen hinzufügen, es sei denn, verwandte Tabellen werden erstellt. Laravel führt die Migrationsreihenfolge nach Datum der Migrationsdateien aus. Wenn Sie also eine Beziehung zu einer Tabelle erstellen möchten, die in der zweiten Migrationsdatei vorhanden ist, schlägt dies fehl.
Ich hatte das gleiche Problem, also habe ich endlich eine weitere Migrationsdatei erstellt, um alle Beziehungen anzugeben.
quelle
Beachten Sie: Wenn Laravel mit einen Tisch aufstellt
Dies ist bei den meisten Migrationen Standard und richtet ein vorzeichenloses Ganzzahlfeld ein. Stellen Sie daher beim Erstellen einer Fremdreferenz von einer anderen Tabelle zu diesem Feld sicher, dass Sie in der Referenzierungstabelle das Feld auf UnsignedInteger und nicht auf das Feld UnsignedBigInteger (was ich angenommen hatte) setzen.
Beispiel: In der Migrationsdatei 2018_12_12_123456_create_users_table.php:
Dann in der Migrationsdatei 2018_12_12_18000000_create_permissions_table.php, die die Fremdreferenz für Benutzer zurückstellt:
quelle
Sie sollten auf diese Weise schreiben
Das Fremdschlüsselfeld sollte nicht signiert sein , hoffe es hilft !!
quelle
Für das Hinzufügen von Fremdschlüsseleinschränkungen in Laravel hat Folgendes für mich funktioniert:
Erstellen Sie die Spalte als Fremdschlüssel wie folgt:
Hinzufügen der Beschränkungslinie unmittelbar nach (1) dh
quelle
Ich weiß, dass dies eine alte Frage ist, aber stellen Sie sicher, dass die richtige unterstützende Engine definiert ist, wenn Sie mit Referenzen arbeiten. Stellen Sie die innodb-Engine für beide Tabellen und den gleichen Datentyp für die Referenzspalten ein
quelle
Als ich einige Jahre nach der ursprünglichen Frage mit Laravel 5.1 hierher kam, hatte ich den gleichen Fehler, da meine Migrationen computergeneriert mit demselben Datumscode waren. Ich ging alle vorgeschlagenen Lösungen durch und überarbeitete sie dann, um die Fehlerquelle zu finden.
Beim Verfolgen von Laracasts und beim Lesen dieser Beiträge glaube ich, dass die richtige Antwort der von Vickies ähnelt, mit der Ausnahme, dass Sie keinen separaten Schemaaufruf hinzufügen müssen. Sie müssen den Tisch nicht auf Innodb decken, ich gehe davon aus, dass Laravel das jetzt tut.
Die Migrationen müssen lediglich korrekt zeitgesteuert sein. Dies bedeutet, dass Sie den Datumscode (später) im Dateinamen für Tabellen ändern, für die Sie Fremdschlüssel benötigen. Alternativ oder zusätzlich verringern Sie den Datumscode für Tabellen, die keine Fremdschlüssel benötigen.
Der Vorteil beim Ändern des Datumscodes besteht darin, dass Ihr Migrationscode einfacher zu lesen und zu warten ist.
Bisher funktioniert mein Code, indem der Zeitcode angepasst wird, um Migrationen, die Fremdschlüssel benötigen, zurückzuschieben.
Allerdings habe ich Hunderte von Tabellen, so dass ich ganz am Ende eine letzte Tabelle nur für Fremdschlüssel habe. Nur um die Dinge zum Fließen zu bringen. Ich gehe davon aus, dass ich diese in die richtige Datei ziehen und den Datumscode ändern werde, während ich sie teste.
Ein Beispiel: Datei 2016_01_18_999999_create_product_options_table. Hier muss die Produkttabelle erstellt werden. Schauen Sie sich die Dateinamen an.
Die Produkttabelle: Diese muss zuerst migriert werden. 2015_01_18_000000_create_products_table
Und schließlich ganz am Ende die Datei, die ich vorübergehend zur Behebung von Problemen verwende, die ich überarbeiten werde, wenn ich Tests für die Modelle schreibe, die ich 9999_99_99_999999_create_foreign_keys.php genannt habe. Diese Schlüssel werden kommentiert, als ich sie herausgezogen habe, aber Sie verstehen es.
quelle
So einfach !!!
Wenn Sie zum ersten Mal eine
'priorities'
Migrationsdatei erstellen, wird Laravel zuerst ausgeführt,'priorities'
solange'users'
keine Tabelle vorhanden ist.wie es eine Beziehung zu einer Tabelle hinzufügen kann, die nicht existiert!.
Lösung: Ziehen Sie Fremdschlüsselcodes aus der
'priorities'
Tabelle heraus. Ihre Migrationsdatei sollte folgendermaßen aussehen:und fügen Sie zu einer neuen Migrationsdatei hinzu, hier ist ihr Name
create_prioritiesForeignKey_table
und fügen Sie diese Codes hinzu:quelle
Stellen Sie sicher, dass Ihre vordere Säule über die Wut der vorderen Schlüsselkolonne hinausgeht
Ich meine, Ihr Vorschlüssel (in der zweiten Tabelle) muss der gleiche Typ Ihres Ponter-Schlüssel sein (in der ersten Tabelle).
Ihr Zeiger-Hauptschlüssel muss eine vorzeichenlose Methode sein. Lassen Sie mich zeigen:
in Ihrer ERSTEN Migrationstabelle:
in Ihrer ZWEITEN Migrationstabelle:
EIN ANDERES BEISPIEL, UM UNTERSCHIEDE ZU SEHEN
in Ihrer ERSTEN Migrationstabelle:
in Ihrer ZWEITEN Migrationstabelle:
SIEHE MYSQL NUMERIC TYPES TABLE RANGES
quelle
Eine Sache, die mir aufgefallen ist, ist, dass wenn die Tabellen eine andere Engine als die Fremdschlüsseleinschränkung verwenden, dies nicht funktioniert.
Zum Beispiel, wenn eine Tabelle verwendet:
Und die anderen Verwendungen
würde einen Fehler erzeugen:
Sie können dies beheben, indem Sie InnoDB am Ende Ihrer Tabellenerstellung wie folgt hinzufügen:
quelle
In meinem Fall habe ich auf eine Ganzzahlspalte
id
in einer Zeichenfolgenspalte verwiesenuser_id
. Ich habe mich verändert:$table->string('user_id')
zu:
$table->integer('user_id')->unsigned();
Hoffe es hilft jemandem!
quelle
Das Wesentliche ist, dass die Fremdmethode verwendet wird
ALTER_TABLE
, um ein bereits vorhandenes Feld in einen Fremdschlüssel zu verwandeln . Sie müssen also den Tabellentyp definieren, bevor Sie den Fremdschlüssel anwenden. Es muss jedoch nicht in einem separatenSchema::
Anruf sein. Sie können beides innerhalb von create wie folgt tun:Beachten Sie auch, dass der Typ von
user_id
so eingestellt ist, dass er nicht mit dem Fremdschlüssel übereinstimmt.quelle
Sie können den booleschen Parameter direkt in der Ganzzahlspalte übergeben und angeben, dass er ohne Vorzeichen sein soll oder nicht. In Laravel 5.4 löste der folgende Code mein Problem.
Hier bedeutet der zweite Parameter false , dass er nicht automatisch inkrementiert werden soll, und der dritte Parameter true bedeutet , dass er ohne Vorzeichen sein soll. Sie können die Fremdschlüsseleinschränkung in derselben Migration beibehalten oder trennen. Es funktioniert bei beiden.
quelle
Wenn keine der oben genannten Lösungen für Neulinge funktioniert, überprüfen Sie, ob beide IDs denselben Typ haben: beide sind
integer
oder beide sindbigInteger
, ... Sie können so etwas haben:Haupttabelle (Benutzer zum Beispiel)
Untergeordnete Tabelle (Prioritäten zum Beispiel)
Diese Abfrage ist fehlgeschlagen, da
users.id
es sich um eineBIG INTEGER
währendpriorities.user_id
einer Abfrage handeltINTEGER
.Die richtige Abfrage in diesem Fall wäre die folgende:
quelle
In meinem Fall hat es nicht funktioniert, bis ich den Befehl ausgeführt habe
Auf diese Weise können Sie die Fremdschlüssel im Erstellungsschema belassen
quelle
Es kann auch Ihre Reihenfolge der Erstellungsmigration sein. Wenn Sie zuerst eine Prioritäts-Tabelle und nach der Benutzertabelle erstellen, ist dies falsch. Wegen der ersten Migration nach Benutzertabelle suchen. Sie müssen also die Reihenfolge der Migration ändern
Verzeichnis
quelle
Für mich wurde die Tabellenspalte, auf die meine untergeordnete Tabelle verwiesen hat, nicht indiziert.
Ignorieren Sie die schreckliche Benennung, sie stammt von einem anderen schrecklich gestalteten System.
quelle
Manchmal kann dieser Fehler aufgrund der Reihenfolge der Migrationen auftreten.
Like Users und Order sind zwei Tabellen
Die Bestelltabelle hat einen Foriegn-Schlüssel für Benutzer (Wenn während der Migration die Bestelltabelle zuerst migriert wird, tritt das Problem auf, da keine Benutzer mit dem Fremdschlüssel übereinstimmen.)
Lösung: Legen Sie einfach Ihre Bestellaktualisierungstabelle zur Aktualisierung unter die Benutzer
Beispiel: In meinem Fall Bildung und Universitätstabelle Bildungstabelle
In der Universität
quelle
Eine Sache, die meiner Meinung nach in den Antworten hier fehlt, und bitte korrigieren Sie mich, wenn ich falsch liege, aber die Fremdschlüssel müssen in der Pivot-Tabelle indiziert werden. Zumindest in MySQL scheint dies der Fall zu sein.
quelle