kosovojs/laravel-pg-identity

PostgreSQL identity columns for Laravel's id() and increments() — replaces legacy serial, zero config

Maintainers

Package info

github.com/kosovojs/laravel-pg-identity

pkg:composer/kosovojs/laravel-pg-identity

Transparency log

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.1.0 2026-08-25 15:11 UTC

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 ALWAYS rejects explicit id inserts unless the query uses OVERRIDING SYSTEM VALUE. If you seed rows with fixed ids, the simplest opt-out is $table->id()->always(false), which gives GENERATED BY DEFAULT behavior while keeping everything else (identity type, primary key, etc). You can also call ->generatedAs() yourself on that column — the package never touches columns where generatedAs is already set — for the same effect.
  • Only affects new migrations/columns — existing serial columns in your database aren't rewritten.
  • Requires Laravel 12–13.
  • If another package also calls Connection::resolverFor('pgsql', ...), last one registered wins.