Updating data in Drizzle ORM stays predictable and fully type-safe, whether you’re modifying a single row, updating multiple records, or running advanced logic using conditions, limits, and CTE-based updates.
Each operation flows the same way — define what to update, specify the condition, and let Drizzle handle the SQL underneath with complete schema awareness.
Before working with updates in Drizzle ORM, ensure the data you need is already created. If you haven’t set up your insert flow yet, start there first.
Update One
To update a single row in Drizzle ORM, you call db.update(), pass the table, define the fields in .set(), and target the row with a typed where condition. Drizzle ensures every column and value matches your schema before executing the query.
Example:
const updatedUser = await db
.update(users)
.set({ email: "abc@a.com" })
.where(eq(users.email, "react@frontend.com"))
.returning();
console.log("Updated Record:", updatedUser);
Update Many
Updating multiple rows in Drizzle ORM follows the same predictable flow as a single update — you define the fields you want to change, set your condition, and Drizzle applies the update to every matching record.
Because the entire operation is tied to your schema, the bulk update stays type-safe, consistent, and easy to maintain across your codebase.
Example:
const updatedUsers = await db
.update(users)
.set({ status: "inactive" })
.where(inArray(users.id, [2, 4, 6]))
.returning();
console.log("Updated Records:", updatedUsers);
Update and Return
When you need the updated data immediately after an update, Drizzle ORM makes it simple. You define the fields to modify, target the row with a typed condition, and append .returning() to get the updated record back in the same operation.
const updatedUser = await db
.update(users)
.set({ name: "Sharukhan" })
.where(eq(users.id, 1))
.returning();
console.log("Updated Record:", updatedUser);
Conditional Updation
Conditional updates in Drizzle ORM let you modify a row only when certain criteria are met. You define the fields to change inside .set(), add your condition in .where(), and Drizzle ensures the update happens only when the condition evaluates to true. This keeps your update logic precise and prevents accidental changes to records that don’t meet your requirements.
Example:
const updatedUser = await db
.update(users)
.set({ badge: "regular" })
.where(
and(
eq(users.status, "active"),
gt(users.loginCount, 5)
)
)
.returning();
console.log("Conditional Update:", updatedUser);
What is the ‘with update’ clause?
In SQL, the WITH clause (also known as Common Table Expressions — CTEs) lets you build temporary result sets that only exist during a single query.
It allows you to:
- Pre-calculate values
- Select specific rows
- Filter or rank records
- Join related tables
- Then feed that result into an
UPDATEquery
Example:
const overdue = db.$with("overdue_users").as(
db.select({ id: users.id }).from(users)
.where(lt(users.lastLogin, ninetyDaysAgo))
);
const result = await db
.with(overdue)
.update(users)
.set({ status: "inactive" })
.where(inArray(users.id, overdue.select({ id: overdue.id })))
.returning();
Summary
By now, you’ve covered every core update pattern in Drizzle ORM — updating a single row, updating many records, returning modified values, applying conditional logic, and even performing advanced updates using CTEs with the WITH clause.
You now have a complete, type-safe workflow for handling updates across simple changes, bulk operations, and complex rule-based updates.