You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel迁移中如何设置PostgreSQL的GENERATED BY DEFAULT AS IDENTITY标识列

在Laravel迁移中配置PostgreSQL标识列(GENERATED BY DEFAULT AS IDENTITY)

刚好之前处理过类似的需求,Laravel默认的$table->id()确实是用PostgreSQL序列来实现自增,但如果想要用原生的IDENTITY列,有两种实用的方法可以实现:


方法一:直接使用原生SQL语句(快速实现)

如果只是单张表需要这种结构,直接用DB::statement()执行原生PostgreSQL语句是最直接的方式,完全贴合你想要的表结构:

use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;

return new class extends Migration
{
    public function up()
    {
        DB::statement("CREATE TABLE color (
            color_id INT GENERATED BY DEFAULT AS IDENTITY,
            color_name VARCHAR NOT NULL
        )");
    }

    public function down()
    {
        DB::statement("DROP TABLE IF EXISTS color");
    }
};

运行迁移后,你可以用PostgreSQL的\d color命令查看表结构,会看到color_id列的定义正是你需要的GENERATED BY DEFAULT AS IDENTITY。


方法二:自定义Schema宏(复用性更高)

如果你的项目中有多张表需要使用IDENTITY列,自定义一个Schema宏会更符合Laravel的开发风格,不用每次都写原生SQL。

步骤1:注册Schema宏

在App\Providers\AppServiceProvider的boot()方法中添加以下代码:

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

public function boot()
{
    Schema::macro('identity', function ($columnName = 'id', $type = 'int') {
        /** @var Blueprint $this */
        return $this->addColumn('identity', $columnName, compact('type'));
    });
}

步骤2:创建自定义列类型

在项目中创建App\Database\Schema\Columns\IdentityColumn.php文件(路径可以根据你的习惯调整),内容如下:

use Illuminate\Database\Schema\Grammars\PostgresGrammar;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Schema\ColumnDefinition;

class IdentityColumn extends ColumnDefinition
{
    public function build(Blueprint $blueprint, PostgresGrammar $grammar)
    {
        $column = $this->name;
        $type = $this->attributes['type'];
        
        // 这里可以根据需求改成GENERATED ALWAYS AS IDENTITY
        return "$column $type GENERATED BY DEFAULT AS IDENTITY";
    }
}

步骤3:在迁移中使用自定义方法

现在你就可以像使用$table->id()一样,用$table->identity()来创建标识列了:

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up()
    {
        Schema::create('color', function (Blueprint $table) {
            $table->identity('color_id', 'int');
            $table->string('color_name')->nullable(false);
        });
    }

    public function down()
    {
        Schema::dropIfExists('color');
    }
};

小提示:区分两种IDENTITY模式

别忘了GENERATED BY DEFAULT和GENERATED ALWAYS的区别:

  • GENERATED BY DEFAULT:允许你手动给标识列插入值,如果不提供值则自动生成
  • GENERATED ALWAYS:强制自动生成值,手动插入会报错(除非使用INSERT ... OVERRIDING SYSTEM VALUE语句)

根据你的业务需求调整对应的SQL语句即可。

内容的提问来源于stack exchange,提问作者Dhairya Lakhera

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 14:17:30