Looking to hire Laravel developers? Try LaraJobs

laravel-aurora-dsql maintained by jgamboa

Description
Laravel driver for Amazon Aurora DSQL: IAM token auth, DSQL-compatible schema builder (inline PK/FK, ASYNC indexes, identity) and migration helpers.
Last update
2026/10/09 02:40 (dev-main)
License
Links
Downloads
2
Tags

Comments
comments powered by Disqus

laravel-aurora-dsql

Laravel (12+) database driver for Amazon Aurora DSQL.

  • Connects with an IAM auth token through the official awslabs/aurora-dsql-pdo-pgsql connector (SSL verify-full, OCC retries).
  • DSQL-compatible schema builder: regular Laravel migrations just work.
    • primary() and foreign() / constrained() are emitted inline in CREATE TABLE.
    • index() / unique() → CREATE [UNIQUE] INDEX ASYNC, waiting for the index build to finish.
    • id() / increments() → bigint generated by default as identity (cache 65536).
    • No schema transactions (DSQL allows a single DDL statement per transaction).
    • Schema::getTables(), db:show, db:wipe and migrate:fresh work.
  • DsqlMigration base class for raw SQL migrations.

Installation

composer require jgamboa/laravel-aurora-dsql

The service provider is auto-discovered. Add a connection to config/database.php:

'dsql' => [
    'driver' => 'dsql',
    'host' => env('DSQL_HOST'),                 // xxxx.dsql.us-east-1.on.aws
    'region' => env('AWS_REGION', 'us-east-1'),
    'username' => env('DSQL_USER', 'admin'),    // 'admin' => dsql:DbConnectAdmin; other roles => dsql:DbConnect
    'database' => 'postgres',                   // DSQL has a single database per cluster
    'profile' => env('DSQL_PROFILE'),           // local AWS profile (e.g. SSO). Leave empty on Lambda/EC2/ECS
    'sslrootcert' => env('DSQL_SSLROOTCERT', 'system'), // 'system' requires libpq 17+
    'occ_max_retries' => 3,
    'wait_for_indexes' => true,                 // wait for CREATE INDEX ASYNC jobs
    'prefix' => '',
    'prefix_indexes' => true,
    'search_path' => 'public',
],

Usage

// A regular migration (no raw SQL)
return new class extends Migration
{
    protected $connection = 'dsql';

    public function up(): void
    {
        Schema::create('products', function (Blueprint $table) {
            $table->uuid('id')->primary();
            $table->foreignUuid('category_id')->constrained()->cascadeOnDelete();
            $table->string('sku')->unique();
            $table->timestamps();
        });
    }
};
// Model: UUID v7 primary keys with HasUuids (Laravel 12+)
class Product extends Model
{
    use HasUuids;

    protected $connection = 'dsql';
}

Transactions with retries on OCC conflicts (SQLSTATE 40001):

DB::connection('dsql')->transaction(fn () => /* ... */, attempts: 3);

DSQL limitations (verified against a live cluster)

Not supported Alternative
Adding a PK / FK / UNIQUE / CHECK to an existing table Declare them in Schema::create(); for unique use ->unique() (an index)
ADD COLUMN with DEFAULT, NOT NULL or a FK Add it nullable → SET DEFAULT → backfill
->change() (changing a column type), SET NOT NULL New table + copy + rename
Nested transactions (SAVEPOINT) Avoid DB::transaction() inside another one
TRUNCATE delete()
Temporary tables, triggers, plpgsql, extensions, advisory locks, sharedLock() —
Full-text search with a language config Only simple is available
CREATE DATABASE One cluster per database

Supported: lockForUpdate, upsert (needs a unique index), JSON/JSONB, CTEs, window functions, views, sequences, language sql functions.

Operational notes: connections last at most 60 minutes (long-running processes must reconnect); the IAM token is signed locally (no network call).

Testing

vendor/bin/phpunit --testsuite Unit
DSQL_HOST=xxxx.dsql.us-east-1.on.aws DSQL_PROFILE=my-profile vendor/bin/phpunit --testsuite Integration

License

MIT