Skip to main content
Version: Latest - 1.0.0-alpha.25

Delete

Use db.delete() to remove rows from a table. The delete builder supports filtering and returning deleted data.

Methods

Query methods (DeleteQuery)

MethodDescription
.where(condition)Filter which rows will be deleted
.returning(cols)Specify columns to return after delete (use "*" for all columns)

Basic Usage

Delete with WHERE

Always use .where() to specify which rows to delete:

import { db } from "./db/index.ts";
import { Users } from "./db/schema.ts";
import { eq } from "durcno";

// Delete a specific user
await db.delete(Users).where(eq(Users.id, 1n));
warning

Without a .where() clause, the delete will remove all rows from the table. Always include a filter unless you intend to delete everything.

Complex Filters

Use filter operators for complex conditions:

import { and, eq, lte, or } from "durcno";

// Delete all admin users
await db.delete(Users).where(eq(Users.type, "admin"));

// Delete users matching multiple conditions
await db
.delete(Users)
.where(
and(eq(Users.type, "user"), lte(Users.createdAt, new Date("2023-01-01"))),
);

// Delete users matching either condition
await db
.delete(Users)
.where(
or(eq(Users.email, "spam@example.com"), eq(Users.username, "spammer")),
);

Returning Deleted Data

Use .returning() to get data from deleted rows:

// Return specific columns from deleted rows
const deleted = await db
.delete(Users)
.where(eq(Users.id, 1n))
.returning({ id: true, username: true });
// Type: { id: bigint; username: string }[]

// Return all columns except some
const deleted = await db
.delete(Users)
.where(eq(Users.id, 1n))
.returning({ createdAt: false });
// Type: { id: bigint; username: string; email: string | null; type: "admin" | "user" }[]

// Return all columns using the wildcard
const deleted = await db.delete(Users).where(eq(Users.id, 1n)).returning("*");
// Type: { id: bigint; username: string; email: string | null; type: "admin" | "user"; ... }[]

Without Returning

Without .returning(), the delete returns null:

const result = await db.delete(Users).where(eq(Users.id, 1n));
// Type: null

Method Chaining Order

.where() and .returning() can be chained in any order:

// These are equivalent
await db.delete(Users).where(eq(Users.id, 1n)).returning({ id: true });
await db.delete(Users).returning({ id: true }).where(eq(Users.id, 1n));

Delete All Rows

To delete all rows from a table (use with caution):

// ⚠️ Deletes ALL rows from the table
await db.delete(Users);
danger

Deleting all rows is irreversible. Consider using a WHERE clause or creating a backup before performing bulk deletions.

Practical Examples

Soft Delete Pattern

Instead of actually deleting, you might update a flag:

// Soft delete - mark as deleted instead of removing
await db
.update(Users)
.set({ deletedAt: sql`NOW()` })
.where(eq(Users.id, 1n));

Delete with Confirmation

Return deleted data to confirm what was removed:

const deletedUsers = await db
.delete(Users)
.where(eq(Users.type, "user"))
.returning({ id: true, username: true, email: true });

console.log(`Deleted ${deletedUsers.length} users:`);
deletedUsers.forEach((user) => {
console.log(` - ${user.username} (${user.email})`);
});

Cascade Considerations

When deleting rows that have foreign key relationships, ensure you handle cascades appropriately in your schema or delete related records first:

// Delete user's posts first (if no cascade)
await db.delete(Posts).where(eq(Posts.userId, 1n));

// Then delete the user
await db.delete(Users).where(eq(Users.id, 1n));
  • Filters — Complete list of filter operators for .where() conditions.