mysql2 on 3306.RdsMySQLDialect extends MySQLDialect and changes only IAMSUPER privilege.| Property | Value |
|---|---|
| Dialect name | rdsmysql |
| Extends | MySQLDialect |
| Driver | mysql2 |
| Cloud SDK | @aws-sdk/rds-signer (IAM only, optional) |
| Default port | 3306 |
| Local runtime | none — hosted service only |
$ npm install ts-prorm-orm mysql2$ pnpm add ts-prorm-orm mysql2$ yarn add ts-prorm-orm mysql2$ bun add ts-prorm-orm mysql2mysql2 is the same driver the mysql dialect uses. Add @aws-sdk/rds-signer only for the token-based logins under Managed and cloud variants.import { Prorm } from 'ts-prorm-orm';
export const db = new Prorm({
dialect: 'rdsmysql',
host: 'mydb.abc123.us-east-1.rds.amazonaws.com',
database: 'app',
username: 'app_user',
password: process.env.DB_PASSWORD,
dialectOptions: {
caBundle: '/etc/ssl/rds/global-bundle.pem',
},
});import { Prorm } from 'ts-prorm-orm';
export const db = new Prorm({
dialect: 'rdsmysql',
url: 'rdsmysql://app_user:secret@mydb.abc123.us-east-1.rds.amazonaws.com:3306/app',
dialectOptions: {
caBundle: '/etc/ssl/rds/global-bundle.pem',
},
});host, port, database, username and password before the dialect is built; any of those passed alongside it wins.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: 'rdsmysql',
host: 'mydb.abc123.us-east-1.rds.amazonaws.com',
database: 'app',
username: 'app_user',
password: process.env.DB_PASSWORD,
dialectOptions: {
caBundle: '/etc/ssl/rds/global-bundle.pem',
},
});import { Prorm } from 'ts-prorm-orm';
export const db = new Prorm({
dialect: 'rdsmysql',
host: 'mydb.abc123.us-east-1.rds.amazonaws.com',
database: 'app',
username: 'app_user', // granted rds_iam; no password
dialectOptions: {
iamAuth: { region: 'us-east-1' }, // or true: the default credential chain
caBundle: '/etc/ssl/rds/global-bundle.pem', // a token is only sent over verified TLS
},
});@aws-sdk/rds-signer installed next to the driver.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,
});[!NOTE] No JSON operator in the WHERE builder DataTypes.JSON()maps toJSON, but this dialect's WHERE builder refusesOp.containson it: Cannot render WHERE condition at meta.contains' is not implemented by its WHERE builder. The statement was not sent, because running it without the condition would match rows it should not.
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(() => {});
});SKIP LOCKED)lock with skipLocked inside a transaction:await db.transaction(async (t) => {
await User.findAll({ where: { name: 'Ada' }, lock: { level: 'UPDATE', skipLocked: true }, transaction: t });
});STRING → VARCHAR(255), auto-increment INTEGER → INT, BOOLEAN → TINYINT(1), DATE → DATETIME, UUID → CHAR(36), JSON → JSON. The type comparison lines the major engines up side by side.iamAuth, tokenProvider, caBundle andrdsProxy, with the same TLS rules as RDS for PostgreSQL.const db = new Prorm({
dialect: 'rdsmysql',
host: 'mydb.abc123.us-east-1.rds.amazonaws.com',
database: 'app',
username: 'app_user',
dialectOptions: { iamAuth: { region: 'us-east-1' }, caBundle: '/etc/ssl/rds/global-bundle.pem' },
});buildCreateIamUserQuery('app_user', { requireSSL: true }):AWSAuthenticationPlugin makes the server switch the login tomysql_clear_password. mysql2 has no password callback, so the dialect'sresolvePoolConfig override installs mysqlAuth()'s mysql_clear_passwordpassword (otherwise mysql2 would hash and send itssl: 'Amazon RDS' profile counts as verified TLS and isRdsMySQLDialect extends MySQLDialect (mysql) andObject.getOwnPropertyNames(RdsMySQLDialect.prototype),| Area | Overridden |
|---|---|
| Connection and execution | resolvePoolConfig |
| DML builders | buildSetBinlogRetentionSql, buildSetReplicationDelaySql |
| DDL and schema | buildCreateIamUserQuery, buildGrantQuery |
| Other | buildKillQuerySql, buildKillSql, buildShowConfigurationSql, buildSkipReplicationErrorSql, buildStartReplicationSql, buildStopReplicationSql, killConnection, killQuery |
SUPERSUPER, FILE, SHUTDOWN nor CREATE
TABLESPACE, and a user can only grant what it holds.| Operation | Result |
|---|---|
buildGrantQuery with SUPER, FILE, SHUTDOWN, CREATE TABLESPACE | refused; for SUPER the message points to the mysql.rds_* procedures |
buildGrantQuery with ALL / ALL PRIVILEGES on *.* | refused (it includes them); ALL on a database is fine |
mysql.rds_* procedures replace the statements that need SUPER:| Builder | SQL |
|---|---|
buildKillSql(id) / killConnection(id) | CALL mysql.rds_kill(id) (instead of KILL id) |
buildKillQuerySql(id) / killQuery(id) | CALL mysql.rds_kill_query(id) (instead of KILL QUERY id) |
buildSetBinlogRetentionSql(hours | null) | CALL mysql.rds_set_configuration('binlog retention hours', n) — 1 to 168; null restores the default |
buildSetReplicationDelaySql('source delay' | 'target delay', s) | CALL mysql.rds_set_configuration(…, s) — 0 to 86400 |
buildShowConfigurationSql() | CALL mysql.rds_show_configuration |
buildStartReplicationSql() / buildStopReplicationSql() | CALL mysql.rds_start_replication / rds_stop_replication |
buildSkipReplicationErrorSql() | CALL mysql.rds_skip_repl_error |
SET GLOBAL.rds_kill andrds_kill_query cannot end sessions of users whose names are longer than 16mysql.rds_set_external_* / GTID procedures for replication<=>, ON DUPLICATE KEY UPDATE). Name-keyedrdsmysql added to behave like mysql.rdsmysql://, rds-mysql://.capabilitiesOf() (src/transaction-support.ts),whereSupportOf() (src/query-builders/expression-render.ts),sqlObjectCapabilitiesOf() (src/sql-objects/capabilities.ts) and the| Capability | rdsmysql |
|---|---|
| Transactions atomic | yes |
| Savepoints | yes |
| Isolation | up to SERIALIZABLE |
| Transaction modes | read-only yes; deferrable no; constraint deferral no |
| RETURNING | not emitted; returning is accepted and ignored |
| Upsert | INSERT … ON DUPLICATE KEY UPDATE |
| JSON column | JSON (JSONB → JSON) |
| Vector column | VECTOR(3) |
| Array column | VARCHAR(255) |
| WHERE builder | 28 operator keys plus the $json: prefix; $and/$or/$not; $exists: no; $in subquery: no; expression operands: no |
| SQL objects | family mysql: triggers yes; procedures yes; functions multiStatement; materialized views emulated (procedure); sequences no; enums inline; RLS no |
| Streaming | queryStream() present; LISTEN absent; createExtension() present |