VibORM
Mutations

delete

Delete records from the database

delete

Remove records from your database.

delete

Delete a single record by unique identifier:

const user = await client.user.delete({
  where: { id: "user_123" },
});
// Returns the deleted record

With Return Fields

const user = await client.user.delete({
  where: { id: "user_123" },
  select: { id: true, email: true },
});
// Type: { id: string; email: string }

With Relations

const user = await client.user.delete({
  where: { id: "user_123" },
  include: { posts: true },  // Include relations in return
});

deleteMany

Delete multiple records matching criteria:

const result = await client.post.deleteMany({
  where: { published: false },
});
// Result: { count: 15 }

Delete All

// Delete all records (use with caution!)
const result = await client.post.deleteMany({});
// or
const result = await client.post.deleteMany();

Examples

// Delete old drafts
await client.post.deleteMany({
  where: {
    published: false,
    createdAt: { lt: new Date("2023-01-01") },
  },
});

// Delete by relation
await client.post.deleteMany({
  where: {
    author: {
      is: { status: "BANNED" },
    },
  },
});

// Delete inactive users
await client.user.deleteMany({
  where: {
    lastLogin: { lt: new Date(Date.now() - 365 * 24 * 60 * 60 * 1000) },
    role: { not: "ADMIN" },
  },
});

Options

delete

await client.user.delete({
  where: { ... },       // Required: unique identifier
  select: { ... },      // Optional: fields to return
  include: { ... },     // Optional: relations to include
});

deleteMany

await client.user.deleteMany({
  where: { ... },       // Optional: filter (all if empty)
});

Cascading Deletes

When a record is deleted, related records are handled based on onDelete:

const post = s.model({
  authorId: s.string(),
  author: s.relation
    .fields("authorId")
    .references("id")
    .onDelete("cascade")  // Delete posts when user is deleted
    .manyToOne(() => user),
});
ActionBehavior
cascadeDelete related records
setNullSet FK to null
restrictPrevent deletion
noActionDatabase default

Soft Delete Pattern

Instead of deleting, mark records as deleted:

const user = s.model({
  id: s.string().id(),
  deleted: s.boolean().default(false),
  deletedAt: s.dateTime().nullable(),
});

// Soft delete
async function softDeleteUser(id: string) {
  return client.user.update({
    where: { id },
    data: {
      deleted: true,
      deletedAt: new Date(),
    },
  });
}

// Query only active records
async function getActiveUsers() {
  return client.user.findMany({
    where: { deleted: false },
  });
}

Examples

Delete User Account

async function deleteAccount(userId: string) {
  // Delete in correct order due to FK constraints
  await client.post.deleteMany({
    where: { authorId: userId },
  });
  
  await client.profile.delete({
    where: { userId },
  }).catch(() => {}); // Ignore if no profile
  
  return client.user.delete({
    where: { id: userId },
  });
}

Cleanup Old Data

async function cleanupOldData() {
  const thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);
  
  const [sessions, logs] = await Promise.all([
    client.session.deleteMany({
      where: { expiresAt: { lt: new Date() } },
    }),
    client.auditLog.deleteMany({
      where: { createdAt: { lt: thirtyDaysAgo } },
    }),
  ]);
  
  console.log(`Deleted ${sessions.count} sessions, ${logs.count} logs`);
}

On this page