Part 3 · 1 chapters · ~8 min
Prisma
Prisma's schema language, the generated client and type inference limits, the query engine and its move from a Rust binary to TypeScript and WASM, relation queries and the relationJoins choice, migrations with the shadow database and drift detection, connection pooling and serverless (Accelerate, driver adapters), reading the generated SQL, and known pathologies.
7
Schema, client and engine
code
// schema.prisma
model Account {
id String @id @default(cuid())
ownerId String
currency String
balanceKobo BigInt @default(0)
postings Posting[]
@@index([ownerId])
}
const accts = await prisma.account.findMany({
where: { ownerId: userId }, include: { postings: { take: 20, orderBy: { createdAt: 'desc' } } },
});
// see the SQL Prisma sends
const prisma = new PrismaClient({ log: [{ emit: 'event', level: 'query' }] });
prisma.$on('query', e => console.log(e.query, e.params, e.duration + 'ms'));| known pathology | mitigation |
|---|---|
| deeply nested include fan-out | select only needed fields; split queries; raw SQL for reports |
| connection storms in serverless | a pooler (PgBouncer, Prisma Accelerate) or driver adapters with HTTP drivers |
| no row locking API (SELECT ... FOR UPDATE) | $queryRaw inside an interactive transaction |
| large migrations generated naively | edit generated SQL (CONCURRENTLY, NOT VALID) before deploying |
PRISMA'S ARCHITECTURE
a schema, a generated client, and a query engine
swipe the figure sideways, or tap expand for full screen
1/5
schema first
schema.prisma declares models and relations in Prisma's own language; it is the source of truth for both the client types and migrations.
one schema for types and migrationsPrisma Schema Language