Prisma adapter
Prisma 7 connects to every database through a driver adapter. @persql/prisma
is that adapter for PerSQL: your Prisma schema and queries stay the same, and
the database behind them becomes an isolated SQLite database you can provision
per app, per tenant, or per agent.
npm install @persql/prisma @persql/sdk @prisma/clientUse provider = "sqlite" in schema.prisma, then:
import { PrismaClient } from "./generated/prisma/client";import { PerSQL } from "@persql/sdk";import { PrismaPerSQL } from "@persql/prisma";
const client = new PerSQL({ token: process.env.PERSQL_TOKEN });const adapter = new PrismaPerSQL({ database: client.database("acme/app") });
const prisma = new PrismaClient({ adapter });
const users = await prisma.user.findMany();Migrations
Section titled “Migrations”Generate migration SQL with prisma migrate diff and apply it with
prisma db execute --file (which runs through the adapter), or use PerSQL’s
own migration tools. prisma migrate dev needs a shadow database for its
schema diffing — pass one explicitly; a schema-only PerSQL branch of the main
database is a natural fit:
const adapter = new PrismaPerSQL({ database: client.database("acme/app"), shadowDatabase: client.database("acme/app-shadow"),});Transactions are not atomic
Section titled “Transactions are not atomic”PerSQL’s HTTP API has no held connection, so prisma.$transaction(...) runs
its statements individually — the same documented trade-off as Prisma’s
Cloudflare D1 adapter. The adapter warns once per process when a transaction
starts. When you need an atomic multi-statement write, drop to the SDK:
await client.database("acme/app").batch( [ { sql: "UPDATE accounts SET balance = balance - 10 WHERE id = ?", params: [1] }, { sql: "UPDATE accounts SET balance = balance + 10 WHERE id = ?", params: [2] }, ], { transaction: true });Other limits
Section titled “Other limits”- Bytes columns are not supported — the wire format is JSON. Store binary data
base64-encoded in a
Stringcolumn. - Affected-row counts and
lastInsertIdcome from SQLite’schanges()andlast_insert_rowid(), which PerSQL reports per write statement.
Local mode for tests
Section titled “Local mode for tests”const adapter = new PrismaPerSQL({ database: new PerSQL({ local: ":memory:" }).database("test/db"),});Runs the same adapter against in-process SQLite — no network, no token.