Browse documentation

Aurora DSQL

The DNML operations for Amazon Aurora DSQL run SQL on a cluster and read its catalog. A request with one of these operations uses DNML version 1.1.

The examples on this page are parts of four complete example files. To run SQL outside a request, use the Aurora DSQL console.

Connection keys

Each Aurora DSQL operation connects to one cluster as one database role. Set the connection keys on the operation, or one time in [defaults].

KeyRequiredRules
clusterArn Yes, on the operation or in [defaults] The form is arn:aws:dsql:<region>:<account-id>:cluster/<cluster-id>. Dynomate resolves templates before it checks the ARN. An ARN that is not valid gives DNML_INVALID_CLUSTER_REFERENCE.
databaseRole Yes, on the operation or in [defaults] For exactly admin, Dynomate signs a dsql:DbConnectAdmin token. For any other role, also Admin, it signs a dsql:DbConnect token.
profileName No The AWS profile that signs the token. The default is the request default, then the profile named default.
region No It must be the AWS Region in the cluster ARN, or the error is DNML_REGION_MISMATCH.

Aurora DSQL operations do not accept endpointUrl, database or tableArn. In the app, set the defaults in Request settings.

This part of inspect-orders.dnml gets the cluster ID from an input:

DNML
[defaults]profileName = "commerce-dev"clusterArn = "arn:aws:dsql:us-east-1:111122223333:cluster/${CLUSTER_ID}"databaseRole = "app_reader"

Connections in a run

  • A run opens one connection for each profile, cluster ARN and database role. Operations with the same three values share the connection, so a SET stays for the later operations.
  • Each connection starts with TimeZone=UTC, DateStyle=ISO and IntervalStyle=iso_8601.
  • The connection uses the saved network settings of the cluster ARN.
  • After a cancellation, a deadline, a lost connection or a failed rollback, Dynomate closes the connection. Later operations on it fail in the same run.
  • Aurora DSQL operations need no confirmation or approval, also as admin. See Aurora DSQL connections.

Required permissions

A request needs dsql:DbConnect on the cluster, or dsql:DbConnectAdmin to connect as admin. It makes no Aurora DSQL API calls, because Dynomate signs the token on your computer. For an example policy, see connection permissions. A request does not need the dsql:GetCluster action of that policy.

Parameters

parameters gives the values for $1, $2 and so on, in order. Each value binds as a PostgreSQL parameter:

DNML valuePostgreSQL parameter
An integerint8
A float, for example 12.5float8
A boolean, or { BOOL = … }bool
A string, or { S = "…" }No type. The server finds the type from the SQL, so a string matches a uuid column without a cast.
{ N = "…" }, or an exact number from an earlier resultnumeric
{ B = "…" }, or binary from an earlier resultbytea
{ NULL = true }, or null from an earlier resultNULL, with no type
A map or a list: { M = … }, { L = … }, or a TOML table or arrayjsonb
A set: SS, NS or BSNot permitted. The error is DNML_TYPE_MISMATCH.
  • With parameters, the SQL must be one statement. Without parameters, the SQL can hold more than one statement.
  • For exact money values, use { N = "12.50" }. A TOML float binds as float8.
  • To reuse a decimal from an earlier result, use a whole-value template. { N = "${…}" } fails with DNML_TYPED_VALUE.

In this part of inspect-orders.dnml, the SQL casts the string $1 to interval, and $2 binds as int8:

DNML
[[dsql.query]]name = "Recent orders"sql = '''SELECT id, status, total, created_atFROM ordersWHERE created_at >= now() - $1::intervalORDER BY created_at DESCLIMIT $2'''parameters = ["7 days", 100]maxRows = 25

Dollar quotes

In DNML, $$ is the escape for one $, so a $$ … $$ body reaches Aurora DSQL as $ … $. Use a tagged dollar quote, for example $fn$ … $fn$. See Escaping in DNML.

Results

dsql.query and dsql.transaction return this result:

Text
{ statements: [ { columns: [ { name, key, type } ], rows: [ { <key>: value } ],                  rowCount, truncated, rowsAffected, commandTag } ],  attempts, elapsedMs }
  • statements has one entry for each statement that the server runs. The BEGIN and COMMIT that Dynomate sends have no entry.
  • The rows use key, which is the column name. Repeated column names get _2, _3 and so on.
  • With maxRows, truncated is true if the server sent more rows than Dynomate kept.

Each value in rows gets a type from its PostgreSQL type:

PostgreSQL typeValue in the result
int2, int4, int8, oidInteger
numericExact decimal
float4, float8Number
boolBoolean
byteaBinary
json, jsonbMaps and lists
NULLnull
Other types, for example text, uuid, dates and timesThe text from the server. Dates and times use UTC and the ISO format.

To use a value in a later operation, refer to the result by the normalized name of the operation, for example ${load_order.statements[0].rows[0].id}. For the CLI output, see Aurora DSQL results in the CLI.

Commit status and retries

When a dsql.query or dsql.transaction fails, details.commitStatus shows what happened to its changes, if Dynomate knows it:

commitStatusMeaning
committedAurora DSQL committed the changes before the error.
rolled-backThe transaction rolled back. No changes were kept.
unknownDynomate does not know if the commit completed. Check the data before you run the request again.

An unknown outcome comes from an XX000 error, a cancellation, a deadline or a lost connection during a commit or an autocommit write. See Unknown commit outcomes.

Retry on conflict

By default, an optimistic concurrency conflict fails the operation. With retryOnConflict = true, Dynomate runs the full operation again after OC000 or OC001, up to 3 attempts in total. It does not retry after an unknown outcome or another error. timeoutMs includes all attempts.

In dsql-ledger.dnml, a retry is safe. The UPDATE reads the balance that it changes, and no value comes from an earlier operation:

DNML
[[dsql.transaction]]name = "Record payment"dependsOn = "Account"statements = [  {    sql = "UPDATE ledger.accounts SET balance = balance - $2, updated_at = now() WHERE id = $1",    parameters = ["${ACCOUNT_ID}", { N = "12.50" }],  },  {    sql = "INSERT INTO ledger.payments (account_id, amount) VALUES ($1, $2)",    parameters = ["${ACCOUNT_ID}", { N = "12.50" }],  },]retryOnConflict = true

Aurora DSQL query

Runs SQL on an Aurora DSQL cluster in autocommit mode and returns the rows and command tag of each statement.

DNML
[defaults]profileName = "commerce-dev"clusterArn = "arn:aws:dsql:us-east-1:111122223333:cluster/exampleclusterid0123456789"databaseRole = "app_writer"[[dsql.query]]name = "Load order"sql = '''SELECT id, status, total, currencyFROM ordersWHERE id = $1 AND status = 'PENDING''''parameters = ["${ORDER_ID}"]
  • Each dsql.query is destructive, also a SELECT, but it needs no confirmation or approval.
  • Dynomate sends the SQL as written and adds no LIMIT. maxRows only limits the rows that Dynomate keeps.
  • If the SQL leaves a transaction open, the result has the warning DNML_DSQL_TRANSACTION_OPEN. A later operation on the same connection must run COMMIT. If not, the transaction rolls back when the run ends.
[[dsql.query]] Destructive

Keys

clusterArn string
The ARN of the Aurora DSQL cluster, in the form arn:aws:dsql:<region>:<account-id>:cluster/<id>. Dynomate gets the Region from it. Set it here or in [defaults]. In the app: Operation header › Cluster ARN
databaseRole string
The database role to connect as. For exactly admin, in lowercase, Dynomate signs a dsql:DbConnectAdmin token. For any other role, also Admin, it signs a dsql:DbConnect token. Set it here or in [defaults]. In the app: Operation header › Database role
sql string Required
The SQL to run in autocommit mode. Without parameters, it can hold several statements, and each statement returns its own result. With parameters, it must be one statement. In the app: SQL tab › SQL
parameters array of values
The values for $1, $2 and so on, in order. Dynomate sends a string with no type, and the server infers the type. A map or a list binds as jsonb. In the app: SQL tab › Parameters
retryOnConflict boolean
If true, Dynomate runs the full operation again after an optimistic concurrency conflict (OC000 or OC001), up to three attempts in total. The default is false. In the app: Execution tab › Retry on conflict
maxRows integer
The maximum number of rows that Dynomate keeps from each statement. The server still sends all rows. The default, 0, keeps all rows. In the app: no field. Edit the file.

DSQL transaction

Runs statements in one transaction, between BEGIN and COMMIT. If a statement fails, Dynomate rolls back the transaction.

DNML
[[dsql.transaction]]name = "Settle"dependsOn = "Load order"statements = [  {    sql = "UPDATE orders SET status = 'SETTLED', settled_at = now() WHERE id = $1 AND status = 'PENDING'",    parameters = ["${load_order.statements[0].rows[0].id}"],  },  {    sql = "INSERT INTO order_events (order_id, event, amount, currency) VALUES ($1, 'settled', $2, $3)",    parameters = ["${load_order.statements[0].rows[0].id}", "${load_order.statements[0].rows[0].total}", "${load_order.statements[0].rows[0].currency}"],  },]
  • If a statement fails, Dynomate sends ROLLBACK. details.statementIndex names the statement.
  • A statement that runs COMMIT or ROLLBACK ends the transaction early. The result then has the warning DNML_DSQL_TRANSACTION_ENDED.
  • The Aurora DSQL limits apply. For example, a transaction cannot mix DDL and DML. The 5-minute limit gives DNML_AWS, not DNML_TIMEOUT.
  • Here, retryOnConflict stays false, because the values come from an earlier operation.
[[dsql.transaction]] Destructive

Keys

clusterArn string
The ARN of the Aurora DSQL cluster, in the form arn:aws:dsql:<region>:<account-id>:cluster/<id>. Dynomate gets the Region from it. Set it here or in [defaults]. In the app: Operation header › Cluster ARN
databaseRole string
The database role to connect as. For exactly admin, in lowercase, Dynomate signs a dsql:DbConnectAdmin token. For any other role, also Admin, it signs a dsql:DbConnect token. Set it here or in [defaults]. In the app: Operation header › Database role
statements array of maps Required
The statements to run between BEGIN and COMMIT, in order. Each statement has sql and optional parameters. In the app: Statements tab › Statements
retryOnConflict boolean
If true, Dynomate runs the full transaction again after an optimistic concurrency conflict (OC000 or OC001), up to three attempts in total. The default is false. In the app: Execution tab › Retry on conflict
maxRows integer
The maximum number of rows that Dynomate keeps from each statement. The server still sends all rows. The default, 0, keeps all rows. In the app: no field. Edit the file.

List schemas

Lists the schemas in an Aurora DSQL cluster, without the system schemas.

DNML
[[dsql.listSchemas]]name = "Schemas"

The result has schemas and count. Each schema has name.

[[dsql.listSchemas]]

Keys

clusterArn string
The ARN of the Aurora DSQL cluster, in the form arn:aws:dsql:<region>:<account-id>:cluster/<id>. Dynomate gets the Region from it. Set it here or in [defaults]. In the app: Operation header › Cluster ARN
databaseRole string
The database role to connect as. For exactly admin, in lowercase, Dynomate signs a dsql:DbConnectAdmin token. For any other role, also Admin, it signs a dsql:DbConnect token. Set it here or in [defaults]. In the app: Operation header › Database role

List DSQL tables

Lists the tables and views in one schema, with an optional name pattern.

DNML
[[dsql.listTables]]name = "Order tables"schema = "public"expression = "order%"

Here, order% matches orders and order_events. The result has tables and count. Each table has schema, name, kind, estimatedRows and comment.

[[dsql.listTables]]

Keys

clusterArn string
The ARN of the Aurora DSQL cluster, in the form arn:aws:dsql:<region>:<account-id>:cluster/<id>. Dynomate gets the Region from it. Set it here or in [defaults]. In the app: Operation header › Cluster ARN
databaseRole string
The database role to connect as. For exactly admin, in lowercase, Dynomate signs a dsql:DbConnectAdmin token. For any other role, also Admin, it signs a dsql:DbConnect token. Set it here or in [defaults]. In the app: Operation header › Database role
schema string Required
The schema to list tables from. In the app: Operation header › Schema
expression string
A case-sensitive SQL LIKE pattern for table names, for example pay%. If you omit it, the operation lists all tables in the schema. In the app: Filter tab › Table name pattern

Describe DSQL table

Returns the columns, primary key, indexes and foreign keys of one table or view.

DNML
[[dsql.describeTable]]name = "Orders table"dependsOn = "Wait for index"schema = "public"tableName = "orders"
  • The result has table, with columns, primaryKey, indexes, foreignKeys, estimatedRows and comment.
  • The state of each index is valid, invalid or building.
  • If the table does not exist, the operation fails with DNML_AWS and the SQLSTATE 42P01.
[[dsql.describeTable]]

Keys

clusterArn string
The ARN of the Aurora DSQL cluster, in the form arn:aws:dsql:<region>:<account-id>:cluster/<id>. Dynomate gets the Region from it. Set it here or in [defaults]. In the app: Operation header › Cluster ARN
databaseRole string
The database role to connect as. For exactly admin, in lowercase, Dynomate signs a dsql:DbConnectAdmin token. For any other role, also Admin, it signs a dsql:DbConnect token. Set it here or in [defaults]. In the app: Operation header › Database role
schema string
The schema of the table. The default is public. In the app: Operation header › Schema
tableName string Required
The name of the table or view to describe. In the app: Operation header › Table

Wait for job

Waits until an asynchronous job, for example an index build, finishes.

DNML
[defaults]profileName = "commerce-admin"clusterArn = "arn:aws:dsql:us-east-1:111122223333:cluster/exampleclusterid0123456789"databaseRole = "admin"[[dsql.query]]name = "Create index"sql = "CREATE INDEX ASYNC orders_by_status ON orders (status, created_at)"[[dsql.waitForJob]]name = "Wait for index"dependsOn = "Create index"timeoutMs = 900000jobId = "${create_index.statements[0].rows[0].job_id}"pollIntervalMs = 2000
  • Wait for index reads the job ID from the job_id column that CREATE INDEX ASYNC returns.
  • The default deadline is 30 minutes. Here, timeoutMs sets 15 minutes.
  • state in the result is completed, or unknown if Aurora DSQL removed the job record. For an index job, indexValid then shows if the index is valid.
  • A failed job fails the operation with DNML_AWS.
[[dsql.waitForJob]]

Keys

clusterArn string
The ARN of the Aurora DSQL cluster, in the form arn:aws:dsql:<region>:<account-id>:cluster/<id>. Dynomate gets the Region from it. Set it here or in [defaults]. In the app: Operation header › Cluster ARN
databaseRole string
The database role to connect as. For exactly admin, in lowercase, Dynomate signs a dsql:DbConnectAdmin token. For any other role, also Admin, it signs a dsql:DbConnect token. Set it here or in [defaults]. In the app: Operation header › Database role
jobId string Required
The job ID that an asynchronous statement returns, for example CREATE INDEX ASYNC. It is usually a reference to the result of that operation. In the app: Job tab › Job ID
pollIntervalMs integer
The time between job status checks, in milliseconds. The default is 1,000. In the app: Execution tab › Poll interval (ms)