J'essaie de créer des clés étrangères dans Laravel cependant quand je migre ma table en utilisant artisan
je reçois l'erreur suivante:
[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`))
Mon code de migration est le suivant:
fichier de migration des priorités
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');
}
fichier de migration des utilisateurs
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');
}
Toutes les idées sur ce que j'ai fait de mal, je veux l'obtenir maintenant, car j'ai beaucoup de tableaux que je dois créer, par exemple utilisateurs, clients, projets, tâches, statuts, priorités, types, équipes. Idéalement, je veux créer des tables qui contiennent ces données avec les clés étrangères, i..e clients_project
et project_tasks
etc.
J'espère que quelqu'un pourra m'aider à démarrer.
Schema::table
méthode, a aidé! Merci!$table->unsignedBigInteger('user_id')
si votre user.id estbigIncrements
Question déjà répondu, mais j'espère que cela pourrait aider quelqu'un d'autre.
Cette erreur s'est produite pour moi car j'ai d'abord créé la table de migration avec la clé étrangère avant que la clé n'existe en tant que clé primaire dans sa table d'origine. Les migrations sont exécutées dans l'ordre dans lequel elles ont été créées, comme indiqué par le nom de fichier généré après l'exécution
migrate:make
. Par exemple2014_05_10_165709_create_student_table.php
.La solution était de renommer le fichier avec la clé étrangère à une date antérieure à celle du fichier avec la clé primaire, comme recommandé ici: http://forumsarchive.laravel.io/viewtopic.php?id=10246
Je pense que je devais aussi ajouter
$table->engine = 'InnoDB';
la source
Laravel ^ 5.8
Exemple
Imaginons que vous construisez une application simple basée sur les rôles et que vous ayez besoin de référencer user_id dans la table PIVOT "role_user" .
2019_05_05_112458_create_users_table.php
2019_05_05_120634_create_role_user_pivot_table.php
Comme vous pouvez le voir, la ligne commentée lèvera une exception de requête, car, comme mentionné dans les notes de mise à niveau, les colonnes de clé étrangère doivent être du même type , vous devez donc soit changer la clé étrangère (dans cet exemple, c'est user_id ) en bigInteger dans la table role_user ou remplacez la méthode bigIncrements par la méthode increments dans la table users et utilisez la ligne commentée dans le tableau croisé dynamique , c'est à vous.
J'espère avoir pu clarifier cette question pour vous.
la source
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'); }
Ça a marché. Je vous remercie.Dans mon cas, le problème était que la table principale contenait déjà des enregistrements et je forçais la nouvelle colonne à ne pas être NULL. Donc, l'ajout d'un -> nullable () à la nouvelle colonne a fait l'affaire. Dans l'exemple de la question serait quelque chose comme ceci:
$table->integer('user_id')->unsigned()->nullable();
ou:
$table->unsignedInteger('user_id')->nullable();
J'espère que cela aide quelqu'un!
la source
Dans mon cas, le problème était que la migration générée automatiquement pour la
users
table étaitJ'ai donc dû changer le type de colonne
pour faire ma migration avec la clé étrangère.
Ceci avec laravel
5.8.2
la source
Dans mon cas, le problème était avec le calendrier de migration, soyez prudent lors de la création de migrations, créez d'abord la migration enfant que la migration de base. Parce que si vous créez d'abord la migration de base, votre clé étrangère recherchera une table enfant et il n'y aura pas de table qui lèvera ensuite une exception.
En outre:
Lorsque vous créez une migration, elle a un horodatage au début. disons que vous avez créé un chat de migration pour qu'il ressemble
2015_08_19_075954_the_cats_time.php
et qu'il ait ce codeEt après avoir créé la table de base, vous créez une autre race de migration qui est une table enfant, elle a sa propre heure et date de création. Le code ressemblera à:
il semble que ces deux tables soient correctes mais lorsque vous exécutez php artisan migrate . Il lèvera une exception car la migration créera d'abord la table de base dans votre base de données car vous avez créé cette migration en premier et notre table de base contient une contrainte de clé étrangère qui recherchera la table enfant et la table enfant n'existe pas, ce qui est probablement une exception..
Alors:
cela fonctionnera
la source
Dans mon cas, je modifie simplement l'ordre dans lequel les migrations sont exécutées manuellement afin que les utilisateurs de table soient créés en premier.
Dans le dossier base de données / migrations / votre nom de fichier de migration a ce format: year_month_day_hhmmss_create_XXXX_table.php
Renommez simplement créer un fichier utilisateur pour que la date de création de votre table de priorités de table soit définie plus tard que la date utilisateur (même une seconde plus tard suffit)
la source
Dans laravel 5.8, la table users_table utilise
bigIncrements('id')
le type de données pour la clé primaire. Ainsi, lorsque vous souhaitez référencer une contrainte de clé étrangère, votreuser_id
colonne doit être deunsignedBigInteger('user_id')
type.la source
J'avais le même problème en utilisant Laravel 5.8. Après avoir regardé de plus près les documents laravel, découvrez ici Migrations & bigIncrements . Je l'ai résolu en ajoutant des clés primaires "$ table-> bigIncrements ('id')" à chaque table liée à la table "users" et à ses associations, dans mon cas la table "role" . Enfin, j'avais "$ table-> unsignedBigInteger" pour associer des rôles aux utilisateurs (plusieurs à plusieurs), c'est-à-dire la table "role_user" .
la source
J'ai eu ce problème avec laravel 5.8 et j'ai corrigé ce code, comme indiqué ici dans la documentation de Laravel , à l'endroit où j'ajoute une clé étrangère.
alors j'ai couru
$ php artisan migrate:refresh
Étant donné que cette syntaxe est plutôt verbeuse, Laravel fournit des méthodes de terser supplémentaires qui utilisent la convention pour fournir une meilleure expérience de développeur. L'exemple ci-dessus pourrait être écrit comme suit:
la source
L'utilisation de Laravel 5.3 a eu le même problème.
La solution consistait à utiliser unsignedInteger au lieu de integer ('name') -> unsigned () .
Voilà donc ce qui a fonctionné
La raison pour laquelle cela a fonctionné est le fait que lorsque vous utilisez entier ('nom') -> non signé, la colonne créée dans la table a une longueur de 11, mais lorsque vous utilisez unsigedInteger ('nom') la colonne avait une longueur 10.
La longueur 10 est la longueur des clés primaires lorsque vous utilisez Laravel, la longueur des colonnes correspond donc.
la source
Cette erreur s'est produite pour moi parce que - alors que la table que j'essayais de créer était InnoDB - la table étrangère à laquelle j'essayais de la relier était une table MyISAM!
la source
Nous ne pouvons pas ajouter de relations, sauf si des tables associées sont créées. Laravel exécute les migrations par ordre de date des fichiers de migration. Donc, si vous souhaitez créer une relation avec une table qui existe dans le 2e fichier de migration, cela échoue.
J'ai rencontré le même problème, j'ai donc finalement créé un fichier de migration pour spécifier toutes les relations.
la source
Attention: lorsque Laravel met en place une table en utilisant
qui est standard dans la plupart des migrations, cela créera un champ entier non signé. Par conséquent, lorsque vous créez une référence étrangère d'une autre table à ce champ, assurez-vous que dans la table de référence, vous définissez le champ sur UnsignedInteger et non (ce que je supposais être un) UnsignedBigInteger.
Par exemple: dans le fichier de migration 2018_12_12_123456_create_users_table.php:
Ensuite, dans le fichier de migration 2018_12_12_18000000_create_permissions_table.php, qui configure la référence étrangère aux utilisateurs:
la source
Vous devez écrire de cette façon
Le champ de clé étrangère ne doit pas être signé , j'espère que cela aide !!
la source
Pour faire l'ajout d'une contrainte de clé étrangère dans laravel, ce qui suit a fonctionné pour moi:
Créez la colonne comme clé étrangère comme suit:
Ajout de la ligne de contrainte immédiatement après (1) ie
la source
Je sais que c'est une vieille question, mais assurez-vous que si vous travaillez avec des références, le moteur de support approprié est défini. définir le moteur innodb pour les deux tables et le même type de données pour les colonnes de référence
la source
J'interviens ici quelques années après la question d'origine, en utilisant laravel 5.1, j'ai eu la même erreur car mes migrations ont été générées par ordinateur avec le même code de date. J'ai parcouru toutes les solutions proposées, puis refactorisé pour trouver la source d'erreur.
En suivant les laracasts et en lisant ces articles, je pense que la bonne réponse est similaire à la réponse de Vickies, à l'exception que vous n'avez pas besoin d'ajouter un appel de schéma distinct. Vous n'avez pas besoin de mettre la table sur Innodb, je suppose que laravel le fait maintenant.
Les migrations doivent simplement être chronométrées correctement, ce qui signifie que vous modifierez le code de date (plus tard) dans le nom de fichier des tables sur lesquelles vous avez besoin de clés étrangères. Alternativement ou en plus, abaissez le code de données pour les tables qui n'ont pas besoin de clés étrangères.
L'avantage de la modification du code de données est que votre code de migration sera plus facile à lire et à maintenir.
Jusqu'à présent, mon code fonctionne en ajustant le code temporel pour repousser les migrations qui nécessitent des clés étrangères.
Cependant, j'ai des centaines de tables, donc à la fin j'ai une dernière table pour les clés étrangères. Juste pour faire bouger les choses. Je suppose que je vais les extraire dans le bon fichier et modifier le code de données pendant que je les teste.
Donc un exemple: fichier 2016_01_18_999999_create_product_options_table. Celui-ci nécessite la création de la table produits. Regardez les noms de fichiers.
la table des produits: celle-ci doit d'abord migrer. 2015_01_18_000000_create_products_table
Et enfin à la toute fin le fichier que j'utilise temporairement pour résoudre les problèmes, que je vais refactoriser en écrivant des tests pour les modèles que j'ai nommés 9999_99_99_999999_create_foreign_keys.php. Ces clés sont commentées lorsque je les ai retirées, mais vous comprenez.
la source
Si simple !!!
si votre premier
'priorities'
fichier de migration de création , Laravel s'exécute d'abord'priorities'
alors que la'users'
table n'existe pas.comment il peut ajouter une relation à une table qui n'existe pas!.
Solution: retirez les codes de clé étrangère du
'priorities'
tableau. votre fichier de migration doit ressembler à ceci:et ajouter à un nouveau fichier de migration, voici son nom
create_prioritiesForeignKey_table
et ajoutez ces codes:la source
assurez-vous que votre colonne étrangère est sur une large rage de colonne clé étrangère
Je veux dire que votre clé étrangère (dans le deuxième tableau) doit être du même type que votre clé ponteuse principale (dans le premier tableau)
votre clé principale de pointeur doit être ajouter une méthode non signée, permettez-moi de montrer:
sur votre première table de migration:
sur votre deuxième table de migration:
UN AUTRE EXEMPLE POUR VOIR LA DIFFÉRENCE
sur votre première table de migration:
sur votre deuxième table de migration:
VOIR LES PLAGES DE TABLEAUX DES TYPES NUMÉRIQUES MYSQL
la source
Une chose que j'ai remarquée est que si les tables utilisent un moteur différent, la contrainte de clé étrangère ne fonctionne pas.
Par exemple, si une table utilise:
Et les autres utilisations
générerait une erreur:
Vous pouvez résoudre ce problème en ajoutant simplement InnoDB à la fin de la création de votre table comme ceci:
la source
Dans mon cas, je faisais référence à une colonne entière
id
sur une colonne de chaîneuser_id
. J'ai changé:$table->string('user_id')
à:
$table->integer('user_id')->unsigned();
J'espère que cela aide quelqu'un!
la source
L'essentiel est que la méthode étrangère utilise
ALTER_TABLE
pour transformer un champ préexistant en clé étrangère. Vous devez donc définir le type de table avant d'appliquer la clé étrangère. Cependant, il n'est pas nécessaire que ce soit dans unSchema::
appel distinct . Vous pouvez faire les deux dans create, comme ceci:Notez également que le type de
user_id
est défini sur non signé pour correspondre à la clé étrangère.la source
Vous pouvez directement passer le paramètre booléen dans la colonne entière en disant qu'il doit être non signé ou non. Dans laravel 5.4, le code suivant a résolu mon problème.
Ici, le deuxième paramètre false indique qu'il ne doit pas être auto-incrémenté et le troisième paramètre true représente qu'il ne doit pas être signé. Vous pouvez conserver la contrainte de clé étrangère dans la même migration ou la séparer. Cela fonctionne sur les deux.
la source
Si aucune des solutions ci-dessus ne fonctionne pour les débutants, vérifiez si les deux ID ont le même type: les deux sont
integer
ou les deux le sontbigInteger
, ... Vous pouvez avoir quelque chose comme ceci:Table principale (utilisateurs par exemple)
Table enfant (priorités par exemple)
Cette requête échouera car
users.id
est unBIG INTEGER
tandis quepriorities.user_id
est unINTEGER
.La bonne requête dans ce cas serait la suivante:
la source
Dans mon cas, cela n'a pas fonctionné jusqu'à ce que j'exécute la commande
de cette façon, vous pouvez laisser les clés étrangères à l'intérieur du schéma de création
la source
Cela peut également être votre ordre de migration de création. Si vous créez d'abord la table des priorités, et après la table des utilisateurs, ce sera faux. En raison de la première migration à la recherche d'une table d'utilisateurs. Vous devez donc modifier l'ordre de migration sur
annuaire
la source
Pour moi, la colonne de table référencée par ma table enfant n'a pas été indexée.
Ignorez la terrible appellation, c'est d'un autre système terriblement conçu.
la source
Parfois, cette erreur peut survenir en raison d'une séquence de migrations.
Comme les utilisateurs et l'ordre sont deux tableaux
La table de commande a la clé foriegn des utilisateurs (pendant la migration si la table de commande migre en premier, cela causera le problème car aucun utilisateur ne correspond à la clé étrangère)
Lösung: Mettez juste votre table de mise à jour de commande sous les utilisateurs pour la mise à jour
Exemple: Dans mon cas, Tableaux de l'éducation et de l'université Tableau de l'éducation
À l'Université
la source
Je pense qu'une chose manque dans les réponses ici, et corrigez-moi si je me trompe, mais les clés étrangères doivent être indexées sur le tableau croisé dynamique. Au moins dans mysql, cela semble être le cas.
la source