kosovojs / laravel-pg-identity
PostgreSQL identity columns for Laravel's id() and increments() — replaces legacy serial, zero config
Requires
- php: ^8.2
- illuminate/database: ^12.0 || ^13.0
- illuminate/support: ^12.0 || ^13.0
Requires (Dev)
- phpunit/phpunit: ^11.0
This package is auto-updated.
Last update: 2026-08-25 15:23:38 UTC
README
PostgreSQL identity columns for Laravel's id() and increments() — replaces legacy serial, zero config.
What it does
On PostgreSQL, Laravel's $table->id() and increments() family generate legacy bigserial/serial columns. This package makes them generate modern identity columns instead, with no configuration required.
-- before "id" bigserial not null primary key -- after "id" bigint not null generated always as identity primary key
Install
composer require kosovojs/laravel-pg-identity
That's it — Laravel's package auto-discovery does the rest.
How it works
The package registers a pgsql connection resolver that swaps in a PostgresConnection subclass. That subclass uses a PostgresGrammar subclass which, for auto-increment integer columns, sets generatedAs/always before delegating back to the parent grammar. Laravel's own existing modifiers then render the generated always as identity ... primary key clause and skip the serial types on their own.
Testing
Unit tests (no DB required):
vendor/bin/phpunit
End-to-end tests (installs the package into a throwaway Laravel app and checks the generated schema against real sqlite/MariaDB/Postgres databases):
docker run -d --name pgidentity-e2e-pg -e POSTGRES_PASSWORD=secret -e POSTGRES_DB=app -p 5432:5432 postgres:17 docker run -d --name pgidentity-e2e-mariadb -e MARIADB_ROOT_PASSWORD=secret -e MARIADB_DATABASE=app -p 3306:3306 mariadb:11 LARAVEL_VERSION=12 ./e2e/run.sh LARAVEL_VERSION=13 ./e2e/run.sh docker rm -f pgidentity-e2e-pg pgidentity-e2e-mariadb
Caveats
GENERATED ALWAYSrejects explicit id inserts unless the query usesOVERRIDING SYSTEM VALUE. If you seed rows with fixed ids, the simplest opt-out is$table->id()->always(false), which givesGENERATED BY DEFAULTbehavior while keeping everything else (identity type, primary key, etc). You can also call->generatedAs()yourself on that column — the package never touches columns wheregeneratedAsis already set — for the same effect.- Only affects new migrations/columns — existing
serialcolumns in your database aren't rewritten. - Requires Laravel 12–13.
- If another package also calls
Connection::resolverFor('pgsql', ...), last one registered wins.