Free tool

DynamoDB Expression Builder

Pick an operation, build the request visually, and copy a correct, reserved-word-safe expression — with its ExpressionAttributeNames and Values — as AWS SDK v3, CLI, boto3, or PartiQL.

Build your request
Generated code
new QueryCommand({
  "TableName": "MyTable",
  "KeyConditionExpression": "#hashKey = :hashKeyValue AND begins_with(#rangeKey, :rangeKeyValue)",
  "ExpressionAttributeNames": {
    "#hashKey": "pk",
    "#rangeKey": "sk"
  },
  "ExpressionAttributeValues": {
    ":hashKeyValue": {
      "S": "USER#123"
    },
    ":rangeKeyValue": {
      "S": "ORDER#"
    }
  }
})

Why hand-writing DynamoDB expressions is error-prone

A DynamoDB request rarely fails on the obvious part. It fails because status is a reserved word and needs a #-alias, because a numeric id was sent as a string and matched nothing, or because a FilterExpression and a ConditionExpression reused the same :v0 placeholder. Each is a small mistake that produces a request that runs but returns the wrong rows — the worst kind to debug.

This builder assembles the whole request from a typed model. Every attribute name is aliased, every value carries an explicit DynamoDB type, and key, filter, condition, and update placeholders live in separate namespaces, so collisions are impossible by construction. The output is built from the type tags, not guessed from your text — a number stays a number, a base64 string stays binary.

Update expressions and conditional writes get the same treatment: atomic counters, if_not_exists, list_append, REMOVE on a list index, ADD/DELETE on sets, and optimistic-locking conditions all assemble into one correct UpdateExpression and ConditionExpression. The PartiQL tab is honest — when a primitive has no PartiQL form, it tells you which one rather than emitting a statement that quietly misbehaves.

Choosing between a Query and a Scan first? Query vs Scan explains the difference, and PartiQL examples covers the SQL-like syntax in depth.

Frequently asked questions

What is an ExpressionAttributeName, and why the # and : prefixes?

DynamoDB expressions can’t reference an attribute name that is a reserved word (like name, status, or size) directly, and a value placeholder keeps the actual data out of the expression string. So every attribute name is aliased with a #-placeholder in ExpressionAttributeNames and every value with a :-placeholder in ExpressionAttributeValues. This builder generates those maps for you, so a reserved word never breaks your request.

Why do I have to choose a type (S, N, B…) for each value?

DynamoDB is typed at the attribute level: the number 5 is { "N": "5" } and the string "5" is { "S": "5" } — different values that match different items. A text input can’t tell them apart, so the builder asks you to tag each value. The emitted SDK, CLI, boto3, and PartiQL output is built from that tag, never guessed from the text, so a numeric id stays a number and a base64 blob stays binary.

Can it build update expressions and conditional writes?

Yes. Update covers SET (including if_not_exists, atomic +/- counters, and list_append), REMOVE (including a list index like #a[2]), ADD (number or set), and DELETE (set members) — combined into one UpdateExpression. Conditional writes add a ConditionExpression to Update, Put, or Delete for optimistic locking (attribute_not_exists, a version check, and so on). Key conditions and value conditions use separate placeholder namespaces so they never collide.

Why is PartiQL sometimes “not expressible”?

PartiQL covers most reads and writes, but a few DynamoDB primitives have no PartiQL form: a conditional INSERT, the set-typed ADD/DELETE update actions, and functions like size(), list_append, and if_not_exists. When your request uses one of those, the PartiQL tab tells you exactly which feature isn’t expressible instead of emitting a statement that would silently do the wrong thing — use the SDK, CLI, or boto3 output for those.

Does my data leave the browser?

No. The builder runs entirely client-side — it generates the expressions and code snippets in your browser and nothing you type is sent to a server. The URL’s “Copy link” feature serialises your request into the link itself so you can share or bookmark it, but that stays in your hands.

Work with DynamoDB without the Console

DynoTable is a fast desktop client for DynamoDB — browse tables, run SQL-style queries, and edit items locally.