AuroraDSQLDialect extendsPostgresDialect and reuses the pg driver, pooling, $n binding,| Property | Value |
|---|---|
| Dialect name | auroradsql |
| Extends | PostgresDialect |
| Driver | pg (+ @aws-sdk/dsql-signer) |
| Default port | 5432 |
| Database | always postgres |
| Cloud SDK | @aws-sdk/dsql-signer |
| Local runtime | none — hosted service only |
$ npm install ts-prorm-orm @aws-sdk/dsql-signer$ pnpm add ts-prorm-orm @aws-sdk/dsql-signer$ yarn add ts-prorm-orm @aws-sdk/dsql-signer$ bun add ts-prorm-orm @aws-sdk/dsql-signerimport { Prorm } from 'ts-prorm-orm';
export const db = new Prorm({
dialect: 'auroradsql',
host: 'abc123.dsql.us-east-1.on.aws', // region is read from the host
username: 'admin', // no password: an IAM token is minted per connection
});import { DataTypes } from 'ts-prorm-orm';
const User = db.define('User', {
id: { type: DataTypes.INTEGER(), primaryKey: true, autoIncrement: true },
email: { type: DataTypes.STRING(255), allowNull: false, unique: true },
name: { type: DataTypes.STRING(100) },
});
await db.sync(); // CREATE TABLE — see Generated SQL belowimport { Op } from 'ts-prorm-orm';
await User.create({ email: 'ada@example.com', name: 'Ada' });
const page = await User.findAll({
where: { name: { [Op.like]: 'A%' } },
order: [['id', 'ASC']],
limit: 20,
offset: 40,
});import { Prorm } from 'ts-prorm-orm';
export const db = new Prorm({
dialect: 'auroradsql',
host: 'abc123.dsql.us-east-1.on.aws',
username: 'admin', // admin gets getDbConnectAdminAuthToken()
});@aws-sdk/dsql-signer installed next to the driver.import { Prorm } from 'ts-prorm-orm';
declare function fetchTokenFromVault(): Promise<string>;
export const db = new Prorm({
dialect: 'auroradsql',
host: 'abc123.dsql.us-east-1.on.aws',
username: 'app_role',
dialectOptions: {
tokenProvider: async () => fetchTokenFromVault(), // takes precedence over the signer
},
});query(), captured with the driver stubbed out. The model layer inlines the values.db.sync() for the model in the Quick start:CREATE TABLEawait User.create({ email: 'ada@example.com', name: 'Ada' });
await User.update({ name: 'Grace' }, { where: { email: 'ada@example.com' } });
await User.destroy({ where: { id: 1 } });await User.upsert({ id: 1, email: 'ada@example.com', name: 'Ada Lovelace' });upsert() also reads the row by primary key before and after the write, to return the instance.await User.findAll({
where: { name: { [Op.like]: 'A%' } },
order: [['id', 'ASC']],
limit: 20,
offset: 40,
});await db.transaction(async (t) => {
await User.create({ email: 'grace@example.com', name: 'Grace' }, { transaction: t });
// A nested transaction is a SAVEPOINT; its failure undoes only its own work.
await db
.transaction(async (sp) => {
await User.destroy({ where: { id: 1 }, transaction: sp });
throw new Error('keep the row');
}, { transaction: t })
.catch(() => {});
});STRING → VARCHAR(255), auto-increment INTEGER → refused, BOOLEAN → BOOLEAN, DATE → TIMESTAMP, UUID → UUID, JSON → JSON. The type comparison lines the major engines up side by side.import { AuroraDSQLDialect } from 'prorm/dialects/auroradsql';
const dialect = new AuroraDSQLDialect({
host: 'abc123.dsql.us-east-1.on.aws', // region is parsed from the host
username: 'admin', // the default
});
await dialect.connect();password, the dialect hands pg a password function that mints a@aws-sdk/dsql-signer for every new pooled connectiongetDbConnectAdminAuthToken() for admin, getDbConnectAuthToken() for anynpm install @aws-sdk/dsql-signer; it is loaded| Option | Meaning |
|---|---|
tokenProvider | Your own () => string | Promise<string>; takes precedence |
password | A pre-minted token, or a token function |
region | Needed only when the host is not <id>.dsql.<region>.on.aws |
tokenExpiresIn | Token lifetime in seconds (DSQL default 900) |
identityCache | CACHE for autoIncrement identity columns (default 65536) |
ssl defaults to { rejectUnauthorized: true }; ssl: false throws.dialect.resolveAuthToken() returns the token the next connection would use.AuroraDSQLDialect extends PostgresDialect (postgres) andObject.getOwnPropertyNames(AuroraDSQLDialect.prototype),| Area | Overridden |
|---|---|
| Connection and execution | connect, listen, notify, startTransaction, unlisten |
| DML builders | buildDeleteQuery, buildSelectQuery, bulkInsert, formatDefaultValue |
| Types | buildAddColumnSql, buildColumnSql, canonicalTypeSql, createEnumType, ensureEnumTypes, getDataTypeSql, unsupportedType |
| DDL and schema | addColumn, addForeignKey, addIndex, attachPartition, buildAddForeignKeySql, buildCreateIndexAsyncSql, buildCreateSequenceSql, buildCreateTableSql, buildTableConstraintSql, changeColumn, createDatabaseSQL, createExtension, createIndex, createIndexAsync, createMaterializedView, createPartition, createPartitionedTable, createPolicy, createSavepointSQL, createSequence, createStoredProcedure, createTable, createTrigger, detachPartition, disableRLS, dropDatabaseSQL, dropExtension, dropPartition, dropPolicy, dropTrigger, enableRLS, refreshMaterializedView, truncateRefusal |
| Introspection | assertLockSupported, getExtensions, getJob, getLockOptions, hasExtension, hasPolicy, hasTrigger, isRetryableError, resolveAuthToken |
| Other | buildJobStatusQuery, buildReferencesSql, buildValidateConstraintSql, buildWaitForJobQuery, indexOptionsToAsync, matviewRefusal, notifyRefusal, partitionRefusal, referentialAction, releaseSavepointSQL, rlsRefusal, rollbackToSavepointSQL, runTransaction, savepointRefusal, serialRefusal, uuidPrimaryKey, waitForJob |
COMMIT40001 and an OCC code in the message:OC000 — another transaction changed the same row;OC001 — the schema catalog changed under this session.AuroraDSQLDialect.isRetryableError(err); // true for 40001 / OC000 / OC001
AuroraDSQLDialect.occConflictCode(err); // 'OC000' | 'OC001' | null
await dialect.runTransaction(async (tx) => {
// may run more than once — keep it idempotent apart from its DB effects
}, { maxRetries: 5, baseDelayMs: 20 });pg errors and on the wrapped Error the inheritedquery() rethrows (which keeps DSQL's message but loses the code).| Limit | Value |
|---|---|
| Isolation | REPEATABLE READ only — anything else throws |
| DDL | one statement per transaction, never mixed with DML |
| Rows modified | 3,000 per transaction (bulkInsert refuses more) |
| Data modified | 10 MiB per transaction |
| Duration | 5 minutes |
SAVEPOINT | not supported — refused |
AURORA_DSQL_LIMITS.SERIAL/BIGSERIAL. An autoIncrement column becomes a bigintCACHE:dialect.buildCreateTableSql('orders', {
id: { type: DataTypes.INTEGER, autoIncrement: true, primaryKey: true },
}, { initialAutoIncrement: 1000 });
// CREATE TABLE "orders" ("id" BIGINT GENERATED BY DEFAULT AS IDENTITY
// (CACHE 65536 START WITH 1000) PRIMARY KEY)bigint, so an INTEGER column is widened —pg returns int8 as a string unless you install a type parser. CACHE must1 (strictly ordered, more coordination) or >= 65536 (unique, not ordereddialect.buildCreateTableSql('t', { id: dialect.uuidPrimaryKey() });
// CREATE TABLE "t" ("id" UUID DEFAULT gen_random_uuid() NOT NULL PRIMARY KEY)PRIMARY KEY, UNIQUE, CHECK and foreign keys (supported sinceNO ACTION/RESTRICT/CASCADE/SET NULL/SET DEFAULT)uniqueKeys become inline UNIQUE (...) constraints,ALTER TABLE can only add a unique constraint USING INDEX.NOT VALID, then validated asynchronously:dialect.buildAddForeignKeySql('items', 'order_id', 'orders', 'id');
// ALTER TABLE "items" ADD CONSTRAINT "items_order_id_fkey" FOREIGN KEY ("order_id")
// REFERENCES "orders" ("id") NOT VALID
dialect.buildValidateConstraintSql('items', 'items_order_id_fkey');
// ALTER TABLE ASYNC "items" VALIDATE CONSTRAINT "items_order_id_fkey"CREATE INDEX is a syntax error on DSQL. addIndex, createIndex andcreateTable({ indexes }) all emit CREATE INDEX ASYNC, which returns ajob_id immediately:const jobId = await dialect.createIndexAsync('orders', {
name: 'orders_customer_idx',
fields: ['customer_id', { column: 'created_at', nulls: 'LAST' }],
include: ['status'],
where: { status: 'open' },
});
// CREATE INDEX ASYNC "orders_customer_idx" ON "orders" ("customer_id",
// "created_at" NULLS LAST) INCLUDE ("status") WHERE "status" = 'open'
await dialect.waitForJob(jobId); // CALL sys.wait_for_job($1)
await dialect.getJob(jobId); // the sys.jobs rowunique, nullsNotDistinct and ifNotExists are supported; USING,CONCURRENTLY, raw expressions and raw-string predicates throw. At most 8 keydialect.buildCreateSequenceSql({ name: 'order_no', cache: 65536, startWith: 101 });
// CREATE SEQUENCE "order_no" CACHE 65536 START WITH 101cache is required. Temporary sequences are refused.addColumn emits name and type only — a default, NOT NULL, key or referenceADD COLUMN takes nothing else).changeColumn throws: there is no ALTER COLUMN ... TYPE and noSET NOT NULL. removeColumn and renameColumn are inherited.| Asked for | What happens |
|---|---|
SERIAL / BIGSERIAL type | Refused — use autoIncrement (identity) or UUID |
ARRAY, INET, CIDR, MACADDR, RANGE columns | Refused — runtime-only or unsupported |
HSTORE, VECTOR, PostGIS, CITEXT | Refused — no extensions |
temporary, partitionBy, inherit, tablespace on createTable | Refused |
Isolation other than REPEATABLE READ | Refused |
SAVEPOINT (all three builders) | Refused |
lock: 'SHARE' / 'NO KEY UPDATE', NOWAIT, SKIP LOCKED | Refused — only FOR UPDATE / FOR KEY SHARE |
truncate: true on delete | Refused — DELETE in batches |
bulkInsert over 3,000 rows | Refused |
createDatabaseSQL / dropDatabaseSQL | Refused — one database per cluster |
| Triggers, extensions, materialized views | Refused; has*/getExtensions report none |
| Policies / RLS | Refused |
| Stored procedures / PL/pgSQL | Refused — LANGUAGE SQL functions only |
LISTEN / UNLISTEN / NOTIFY | Refused |
createEnumType | Refused — no CREATE TYPE |
| All five partitioning entry points | Refused |
changeColumn, extras on addColumn | Refused |
CREATE DOMAIN,ON CONFLICT upserts, FOR UPDATE, foreign keys, COMMENT ON, and the wholeSELECT grammar.capabilitiesOf() (src/transaction-support.ts),whereSupportOf() (src/query-builders/expression-render.ts),sqlObjectCapabilitiesOf() (src/sql-objects/capabilities.ts) and the| Capability | auroradsql |
|---|---|
| Transactions atomic | yes |
| Savepoints | yes |
| Isolation | up to SERIALIZABLE |
| Transaction modes | read-only yes; deferrable yes; constraint deferral yes |
| RETURNING | RETURNING on INSERT |
| Upsert | INSERT … ON CONFLICT (…) DO UPDATE |
| JSON column | JSON (JSONB → JSONB) |
| Vector column | refused — Aurora DSQL cannot store pgvector types (it has no extensions) (column type 'VECTOR'). |
| Array column | refused — Aurora DSQL cannot store array columns (arrays exist only at query runtime — store the list as JSONB, or as rows in a child table) (column type 'ARRAY'). |
| WHERE builder | 62 operator keys; $and/$or/$not; $exists: yes; $in subquery: yes; expression operands: yes |
| SQL objects | family unknown: triggers no; procedures no; functions no; materialized views no; sequences no; enums check; RLS no |
| Streaming | queryStream() present; LISTEN present; createExtension() present |
tests/dialects/auroradsql.test.ts exercises the dialect with a mocked driver, so nothing touches a server.