Skip to content
Quest 09Intermediate16 min

Speaking DynamoDB's Language (Expression Attributes)

You've mastered the core operations of Kanto — but before you step into Johto's advanced patterns, you need to speak DynamoDB's language fluently.

Almost every Query, Update, and Condition you'll write from here on leans on two kinds of placeholder: ExpressionAttributeValues for the data you compare or write, and ExpressionAttributeNames for the attribute names themselves. Master these and no expression in Johto can surprise you.
Start the lesson

What you'll learn

  • Placeholders starting with : live in ExpressionAttributeValues and stand in for actual data values.
  • Placeholders starting with # live in ExpressionAttributeNames and stand in for attribute names.
  • You must alias a name with # whenever the attribute's name is a DynamoDB reserved word (like Status, Name, or Type) or contains special characters such as . or -.

Section 01

Values: the ':' placeholders

You never paste raw data directly into an expression string. Instead you write a placeholder like :atk and bind the real value separately in ExpressionAttributeValues. DynamoDB substitutes it safely at runtime — this prevents injection-style mistakes and lets the Document Client convert each value to the correct DynamoDB type.

The expression references :atk; the actual number 120 is bound on the side. You can change the value without ever editing the expression string. (Attack isn't a reserved word, so it's safe to use directly — more on that next.)

Binding a value with :JavaScript
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocumentClient, UpdateCommand } from "@aws-sdk/lib-dynamodb";

const client = new DynamoDBClient({ region: "ap-south-1" });
const docClient = DynamoDBDocumentClient.from(client);

await docClient.send(new UpdateCommand({
  TableName: "Pokemon",
  Key: { Name: "Mew" },
  UpdateExpression: "SET Attack = :atk",
  ExpressionAttributeValues: {
    ":atk": 120,
  },
}));

Section 02

Names: the '#' placeholders & reserved words

DynamoDB reserves hundreds of words — Status, Name, Type, Comment, and many more. If one of your attributes is named after a reserved word, using it directly in an expression throws a validation error.

The fix is an ExpressionAttributeName: a placeholder starting with # that stands in for the attribute name itself.

Attribute nameReserved?How to reference it
AttackNoUse directly: SET Attack = :v
StatusYesAlias it: SET #s = :v
NameYesAlias it: attribute_exists(#n)

When in doubt, alias the name — using # always works, reserved or not.

Your appAWS SDK v3DynamoDBtableP0P1P2P3CONSUMED0

Ready · 3 steps · Orbi

This animation plays when you scroll to it. Press Play to start it now.

All steps as text
  1. Your app sends UpdateItem to the Pokemon table with Name = "Mew". UpdateExpression "SET Status = :status"
  2. DynamoDB hashes "Mew" to 416a585c, which routes the request to partition P0.
  3. DynamoDB responds with ValidationException: Status is a reserved keyword, so the expression is rejected before anything is written.

Section 03

Putting them together

Most real expressions use both at once: # for the attribute name and : for its value.

Read it as: “Set the attribute #status (which is really Status) to the value :status (which is "Champion").”

Updating a reserved-word attributeJavaScript
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocumentClient, UpdateCommand } from "@aws-sdk/lib-dynamodb";

const client = new DynamoDBClient({ region: "ap-south-1" });
const docClient = DynamoDBDocumentClient.from(client);

await docClient.send(new UpdateCommand({
  TableName: "Pokemon",
  Key: { Name: "Mew" },
  UpdateExpression: "SET #status = :status",
  ExpressionAttributeNames: {
    "#status": "Status",
  },
  ExpressionAttributeValues: {
    ":status": "Champion",
  },
}));

Practice

Your turn

Time to crown Mew the Champion. Mew's record has a Status attribute — but Status is a DynamoDB reserved word, so it can't go straight into the expression. Alias it with a # name placeholder and bind the new value with a : value placeholder.
Use UpdateExpression: "SET #status = :status", map "#status" to "Status" in ExpressionAttributeNames, and bind :status to "Champion" in ExpressionAttributeValues.
Tab inserts two spaces. Press Escape, then Tab, to leave the editor. Control or Command plus Enter runs the code.
Simulated — no AWS calls

Check

Check your understanding

Quick Quiz · one question, as many tries as you need.

Your Pokémon item has an attribute named Status — a DynamoDB reserved word. How do you safely set it in an UpdateExpression?

Choose one answer.