Eloquent知道实际的主(复合)密钥有问题

时间:2016-08-29 18:43:06

标签: mysql sql laravel eloquent mariadb

数据库中有一个表格,其中包含以下初始迁移:

public function up()
    {
        Schema::create('products_markets', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('product_id')->unsigned();
            $table->foreign('product_id')->references('id')->on('products');
            $table->integer('country_code_id')->unsigned();
            $table->timestamp('created_at')->useCurrent();
            $table->timestamp('updated_at')->useCurrent();
        });

    $sql = 'ALTER TABLE `products_markets` ADD UNIQUE `unique_index`(`product_id`, `country_code_id`)';
    DB::connection()->getPdo()->exec($sql);
}

/**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
    Schema::dropIfExists('products_markets');
}

一切都很好;但是,一旦realized有一个自动递增的主键id没有意义,就会进行新的迁移:

public function up()
    {
        Schema::table('products_markets', function (Blueprint $table) {
            DB::unprepared("ALTER TABLE products_markets ADD INDEX country_code_id (country_code_id)");
            DB::unprepared('ALTER TABLE products_markets MODIFY id INT NOT NULL');
            DB::unprepared('ALTER TABLE products_markets DROP PRIMARY KEY');
            DB::unprepared('ALTER TABLE products_markets DROP COLUMN id');
            DB::unprepared('ALTER TABLE products_markets ADD PRIMARY KEY (country_code_id, product_id)');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('products_markets', function (Blueprint $table) {
            DB::unprepared('DROP INDEX country_code_id ON products_markets');
            DB::unprepared('ALTER TABLE products_markets DROP PRIMARY KEY');
            $table->increments('id');
        });
    }

虽然此代码在我们的服务器上运行,而在某些机器上运行,但其他计算机似乎在测试期间抛出错误:

  

ProductTest :: test_scopeMarket_only_returns_products_for_user_country   Illuminate \ Database \ QueryException:SQLSTATE [42S22]:找不到列:   1054'where子句'中的未知列'id'(SQL:更新   products_markets设置country_code_id = 121,updated_at =   2016-08-29 17:05:21其中id为空)

以下行中的测试错误:

$products[0]->markets()->first()->update(['country_code_id' => 121]);

我们有composer dumpautoload,重新迁移,清除缓存;然而,似乎没有任何帮助。这是否与使用DB::unpreparedALTER表格有关?

1 个答案:

答案 0 :(得分:1)

答案是eloquent does not support composite primary keys

如果你跑:

$products[0]->markets()->update(['country_code_id' => 121]);

它会运行;但是,如果你跑:

$products[0]->markets()->get()->update(['country_code_id' => 121]);

它将失败,因为first()返回一个模型,默认模型primaryKey为id,而复合primaryKey不由Eloquent处理。