【问题标题】:Laravel - there is no unique constraint matching given keys for referenced table - using multiple uniquesLaravel - 没有唯一约束匹配引用表的给定键 - 使用多个唯一性
【发布时间】:2021-03-06 05:55:38
【问题描述】:

我在 Postgres 7.2 中遇到此错误:

无效的外键:7 错误:没有唯一约束匹配给定键的引用表“holiday_items”(SQL:更改表“holiday_bookings”添加约束“holiday_items_parent_holiday_item_id_foreign”外键(“parent_holiday_item_id”)引用“holiday_items”(“ id") 删除级联)

这是我正在尝试运行的迁移:

Schema::create('holiday_bookings', function (Blueprint $table) {
    $table->uuid('id')->primary();
    $table->uuid('booking_id')->index();
    $table->integer('booking_version')->index();
    $table->uuid('parent_holiday_item_id')->nullable();

    $table->unique(["id", "booking_id", "booking_version"]);

    $table->foreign('parent_holiday_item_id')->nullable()->references('id')->on('holiday_items')->onDelete('cascade');
    $table->foreign('quotation_id')->references('id')->on('quotations')->onDelete('cascade');

    $table->timestamps();
});

下面是 holiday_items 表中带有 unqiue 约束的字段:

Schema::create('holiday_items', function (Blueprint $table) {
    $table->uuid('id');
    $table->integer('booking_version')->index();
    $table->uuid('booking_id')->index();
    $table->timestamps();

    $table->unique(["id", "booking_id", "booking_version"]);

    $table->foreign(['booking_version', 'booking_id'])->references([
        'booking_version',
        'id'
    ])->on('bookings')->onDelete('cascade');

});

我在 holiday_bookings 迁移中分配的外键有什么问题?

【问题讨论】:

  • 您是否尝试过对 parent_holiday_item_id 字段使用 onUpdate('cascade')?

标签: laravel postgresql migration


【解决方案1】:

那是因为您的 holiday_items.id 列没有唯一约束。

修改如下:

Schema::create('holiday_items', function (Blueprint $table) {
    $table->uuid('id')->unique();
                      ^^^^^^^^^^
    // ..
});

【讨论】:

  • 这里不应该定义唯一约束吗:$table->unique(["id", "booking_id", "booking_version"]);
  • @f7n 不是真的。该唯一约束用于 3 列值的组合,这意味着您可以重复其中两个并修改第三个以使组合仍然是唯一的。
  • 我刚刚对此进行了测试,但它不是这样工作的。使用 3 列唯一约束和 id 字段上的 primary(),我不能重复其中两个值,因为 id 上的唯一约束失败。
  • @f7n 是的,如果您还添加了primary() 子句,则该值必须是唯一的。请记住,在您的原始代码中并非如此,这就是我在回答您的问题时发表评论的原因。
【解决方案2】:

您应该将 id 列设置为主键,这是该列获得唯一性的地方

在您的迁移中:

 $table->uuid('id');
  $table->primary('id');

并且在您的迁移中无需将此列设置为唯一

【讨论】:

  • 其实@f7n,这个其他答案更准确。
  • 添加primary() 消除了错误,但我不希望表在id 上是唯一的,而是idbooking_version 的组合。那可能吗?这就是我添加这一行的原因:$table->unique(["id", "booking_id", "booking_version"]);
  • 我刚刚对此进行了测试,并将primary() 添加到ID 也为字段添加了唯一约束,但我需要能够添加具有相同ID 但不同@ 的多条记录987654328@。我该怎么办?
  • 你应该使主要约束由不止一列组成:$table->primary(['id', 'booking_versions']);
猜你喜欢
  • 2017-08-11
  • 1970-01-01
  • 2016-04-13
  • 2022-09-27
  • 2012-01-09
  • 2015-11-13
  • 2014-02-17
  • 1970-01-01
相关资源
最近更新 更多