Writing data
await db.user.create({ data: { email: 'a@x.co', name: 'A' } }); // id auto-generated
await db.user.createMany({ data: [ /* … */ ] });
await db.user.update({ where: { id: 'u1' }, data: { name: 'A2' } });
await db.user.updateMany({ where: { active: false }, data: { active: true } });
// update if found, otherwise create
await db.user.upsert({
where: { email: 'a@x.co' },
create: { email: 'a@x.co', name: 'A' },
update: { name: 'A' },
});
await db.user.delete({ where: { id: 'u1' } });
await db.user.deleteMany({ where: { active: false } });Create and update can also return only selected fields or include relations, the same way reads do, by passing select or include alongside data.
Atomic number ops
For number columns you can apply an operation instead of setting a value outright. All four are compiled to a single atomic write per dialect.
await db.post.update({
where: { id: 'p1' },
data: {
views: { increment: 1 }, // also: decrement, multiply, divide, set
score: { multiply: 2 },
rank: { divide: 2 },
published: true,
},
});Pair an atomic op with col() in where for a single-statement, race-safe guard (see Comparing two columns).
Operator objects are validated against the column (since 2.7): a typo like { incrment: 5 }, a numeric op on a string column, or two ops in one object ({ set: 1, increment: 2 }) throws instead of silently writing the object into the field.
For an atomic seeded counter, upsert with an increment — insert applies create only, update applies update only (Prisma semantics, race-safe):
const row = await db.counter.upsert({
where: { key: 'invoice-number' },
create: { key: 'invoice-number', seq: 1000 }, // first call → 1000
update: { seq: { increment: 1 } }, // later calls → 1001, 1002, …
});Writing related records in one call
When you create or update a row you can act on its relations at the same time:
await db.user.create({
data: {
email: 'a@x.co', name: 'A',
posts: {
create: { title: 'Hello' }, // create a new related post
connect: { id: 'p2' }, // attach an existing one
},
},
});Supported on a relation: create, createMany, connect, connectOrCreate (find one or make it), disconnect, set, delete, deleteMany, update, updateMany, upsert.
Deletes and cascades
If a relation declares onDelete: 'Cascade', deleting the parent deletes the children too. On SQL this is enforced by a foreign key. On Mongo, which has no foreign keys, forge walks the relations and deletes the children for you.
await db.user.delete({ where: { id: 'u1' } }); // posts with onDelete:'Cascade' go tooSee more — docs/MUTATIONS.md for create/update/upsert/delete asymmetry, atomic ops, nested writes, batched throughput, and eight worked patterns. docs/UPSERT.md for per-dialect emit (ON CONFLICT / ON DUPLICATE KEY / MERGE / findOneAndUpdate) and race semantics. docs/BATCH.md for createMany/updateMany/deleteMany, bind-parameter limits, chunking. docs/LOCKING.md for SELECT FOR UPDATE / advisory locks / SKIP LOCKED work queues. docs/CONCURRENCY.md for optimistic vs pessimistic control and ETag/If-Match patterns. docs/IDEMPOTENCY.md for the Stripe-style Idempotency-Key model.