PrismaJuniorCoding
Как выполнять CRUD-операции с Prisma Client (create, findUnique, findMany, update, delete)?
Prisma Client: create/createMany создают записи, findUnique/findMany читают (с select, orderBy, пагинацией), update/upsert обновляют, delete/deleteMany удаляют. findUnique возвращает null при отсутствии, update и delete бросают P2025.
CRUD-операции с Prisma Client
Prisma Client предоставляет типобезопасные методы для всех базовых операций. Рассмотрим каждый на конкретном примере с моделью User.
Create — создание записи
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
// Создать одного пользователя
const user = await prisma.user.create({
data: {
email: 'alice@example.com',
name: 'Alice',
posts: {
create: { title: 'Hello World' }, // вложенное создание
},
},
include: { posts: true }, // вернуть связанные посты
});
// Создать несколько сразу
const result = await prisma.user.createMany({
data: [
{ email: 'bob@example.com', name: 'Bob' },
{ email: 'carol@example.com', name: 'Carol' },
],
skipDuplicates: true, // пропустить дубликаты по unique-полям
});
console.log(result.count); // число реально вставленных строк
FindUnique и FindMany — чтение
// Найти одного по уникальному полю — возвращает null, если не найден
const alice = await prisma.user.findUnique({
where: { email: 'alice@example.com' },
select: { id: true, name: true, posts: { select: { title: true } } },
});
// Найти многих с фильтрацией, сортировкой и пагинацией
const users = await prisma.user.findMany({
where: {
name: { contains: 'li', mode: 'insensitive' },
createdAt: { gte: new Date('2024-01-01') },
},
orderBy: { createdAt: 'desc' },
skip: 0,
take: 20,
});
Update — обновление
// Обновить по уникальному условию — бросает исключение, если не найден
const updated = await prisma.user.update({
where: { id: 1 },
data: {
name: 'Alice Smith',
posts: {
updateMany: {
where: { published: false },
data: { published: true },
},
},
},
});
// Создать или обновить (upsert)
const upserted = await prisma.user.upsert({
where: { email: 'dave@example.com' },
create: { email: 'dave@example.com', name: 'Dave' },
update: { name: 'Dave Updated' },
});
Delete — удаление
// Удалить одного — бросает PrismaClientKnownRequestError (P2025), если не найден
const deleted = await prisma.user.delete({
where: { id: 1 },
});
// Удалить многих по условию
const { count } = await prisma.user.deleteMany({
where: { createdAt: { lt: new Date('2023-01-01') } },
});
Подводные камни
findUniqueвозвращаетnull(не бросает), аupdateиdeleteбросаютP2025— нужно обрабатывать оба случая по-разному.findFirstбезorderByвозвращает произвольную строку — в production всегда указывайте порядок сортировки.createManyне поддерживает вложенные связи (include/createвнутриdata) — нужен цикл или$transaction.- Отсутствие
select/includeвозвращает все поля, включаяpasswordHash— всегда явно указывайте нужные поля в API-слое. updateManyиdeleteManyвозвращают только{ count }, не сами записи — если нужны данные, используйтеfindMany+$transaction.- N+1 проблема:
findMany+ цикл сfindUniqueвнутри — всегда заменяйте наincludeилиselectс вложенным отношением. - Prisma не подставляет параметры как prepared statements автоматически при raw-запросах через
$queryRaw— используйте tagged template literals, а не конкатенацию строк.
Common mistakes
- Путает Prisma Client API с гарантиями базы данных: индексы, блокировки и isolation level не создаются магически.
- Не объясняет, где в lifecycle находится CRUD-операции Prisma Client.
- Не разделяет validation, authorization, business logic и persistence.
- Игнорирует ошибки, лимиты входных данных, observability и тестирование.
What the interviewer is testing
- Может объяснить CRUD-операции Prisma Client на примере кода.
- Называет ключевые API: create, findUnique, findMany, update, delete.
- Отделяет ORM/query builder поведение от реального поведения СУБД.
- Видит production-риски: безопасность, отказоустойчивость, логирование и тесты.