无法使用 laravel 数据库迁移创建外键
Posted
技术标签:
【中文标题】无法使用 laravel 数据库迁移创建外键【英文标题】:Can't create foreign key with laravel database migration 【发布时间】:2017-08-16 13:58:57 【问题描述】:我的 Laravel 迁移有问题 :(
当我运行 php artisan migrate 时,它会在外键上停止。
第一次迁移
/**
* Run the migrations.
*
* @return void
*/
public function up()
Schema::enableForeignKeyConstraints();
Schema::create('fichefrais', function (Blueprint $table)
$table->char('idVisiteur', 4);
$table->foreign('idVisiteur')->references('id')->on('visiteur');
$table->char('mois',6);
$table->primary(['idVisiteur', 'mois']);
$table->integer('nbJustificatifs');
$table->decimal('montantValide', 10, 2);
$table->date('dateModif');
$table->char('idEtat', 2);
$table->foreign('idEtat')->references('id')->on('etat');
);
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
Schema::dropIfExists('fichefrais');
第二个
/**
* Run the migrations.
*
* @return void
*/
public function up()
Schema::enableForeignKeyConstraints();
Schema::create('lignefraishorsforfait', function (Blueprint $table)
$table->integer('id');
$table->primary('id');
$table->char('idVisiteur', 4);
$table->char('mois',6);
$table->foreign('idVisiteur')->references('idVisiteur')->on('fichefrais');
$table->foreign('mois')->references('mois')->on('fichefrais');
$table->char('libelle', 100);
$table->date('date');
$table->decimal('montant', 10, 2);
);
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
Schema::dropIfExists('lignefraishorsforfait');
运行命令后,我得到了这个错误:
[照亮\数据库\查询异常] SQLSTATE[HY000]:一般错误:1005 无法创建表 gsb_larave.#sql-176_b9 (errno: 150 "外键约束是 格式不正确”)(SQL:alter table lignefraishors forfait 添加约束 lignefraishorsforfait_mois_foreign 外键 (mois) 在更新时删除级联引用 fichefrais (mois) 级联)
[PDO异常] SQLSTATE[HY000]:一般错误:1005 无法创建表 gsb_laravel.#sql-176_b9 (errno: 150 "外键约束是 格式不正确")
【问题讨论】:
问题可能是您在fichefrais
上有一个复合主键,并且您在lignefraishorsforfait
上的两个不同的FK 上引用它。也许试试$table->foreign(array('idVisiteur', 'mois')->references(array('idVisiteur', 'mois')->on('fichefrais');
我以为是这样的,所以我尝试了你的解决方案,但我仍然有同样的错误。当我尝试使用 phpmyadmin 创建外键时,错误涉及列类型,但它是相同的
【参考方案1】:
使用此迁移:
第一次迁移(fichefrais):
public function up()
Schema::create('fichefrais', function (Blueprint $table)
$table->integer('idVisiteur')->unsigned()->nullable();
$table->foreign('idVisiteur')->references('id')->on('visiteur');
$table->char('mois',6);
$table->primary(['idVisiteur', 'mois']);
$table->integer('nbJustificatifs');
$table->decimal('montantValide', 10, 2);
$table->date('dateModif');
$table->integer('idEtat')->unsigned()->nullable();
$table->foreign('idEtat')->references('id')->on('etat');
);
第二次迁移(lignefraishorsforfait):
public function up()
Schema::create('lignefraishorsforfait', function (Blueprint $table)
$table->integer('id');
$table->primary('id');
$table->integer('mois')->unsigned()->nullable();
$table->foreign('mois')->references('mois')->on('fichefrais');
$table->integer('idVisiteur')->unsigned()->nullable();
$table->foreign('idVisiteur')->references('idVisiteur')->on('fichefrais');
$table->char('libelle', 100);
$table->date('date');
$table->decimal('montant', 10, 2);
);
【讨论】:
【参考方案2】:首先,您的外键必须引用主键(大部分时间是“id”列)。
您还应该按以下顺序创建表:
1- 'etat' 表(我没有看到你没有发布迁移代码,),
2- 'fichefrais' 表,
3- 'lignefraishorsforfait' 表。 只需像这样更改数据库/迁移的日期(示例):
2020_09_11_150331_create_etat_table.php
2020_09_12_000000_create_fichefrais_table.php
2020_09_13_000000_create_lignefraishorsforfait_table.php
您不能先创建包含外键的表,因为没有可引用的键。
【讨论】:
【参考方案3】:问题在于您声明的外键没有引用主键。如果要为非主键创建外键,则 'fichefrais' 表中的 'mois' 列必须 是具有 唯一约束 的列
【讨论】:
【参考方案4】:您的 visiteur 表是否有一个 id 作为主键?如果是,它是否有 数据类型 有 char 和 length 4。 ** lignefraishorsforfait** 表中的 idVisiteur 的数据类型必须与 visiteur 表中的主键相同。
【讨论】:
【参考方案5】:您使用的是 mysql,所以您的表是在 InnoDB 引擎中定义的吗? MyISAM 不接受外键...
【讨论】:
这最好是作为评论而不是作为答案。以上是关于无法使用 laravel 数据库迁移创建外键的主要内容,如果未能解决你的问题,请参考以下文章