feat(compat): Prisma 7 driver adapter for PostgreSQL and MySQL#175
Merged
Conversation
Adds data-api-client/compat/prisma — a drop-in Prisma 7 driver adapter so Prisma Client runs over the Aurora RDS Data API for both engines, via createPrismaPgAdapter / createPrismaMySQLAdapter. The adapter is thin: it holds a core init() client and reuses its query send/retry/result-formatting and beginTransaction/commit/rollback methods. New code is confined to: - prisma-types.ts: columnMetadata.typeName -> Prisma ColumnType mapping (pg + mysql) - prisma-params.ts: $1/? placeholder rewrite, argType -> Data API param building, and the Postgres array ARRAY[...] rewrite (the Data API can't bind array params) - prisma.ts: adapter/transaction/factory classes - errors.ts: mapToPrismaError -> Prisma DriverAdapterError (lazy-requires the optional peer dep @prisma/driver-adapter-utils) Two small core fixes surfaced and are covered by regression tests: - results.ts: nest array-column cells instead of flattening them under hydrateColumnNames:false - params.ts: honor an explicit param-level typeHint Transactions map to the native Data API lifecycle; nested savepoints are rejected. Migrations are documented, not implemented (driver adapters cover the runtime path only — point Prisma's migration url at the Aurora endpoint, like Neon/PlanetScale, or generate SQL offline and apply it over the adapter).
…(PG + MySQL) Opt-in audits exercising the full Prisma Client query surface over the Data API on both engines (179 tests: 99 pg, 80 mysql): CRUD, aggregation/groupBy, all filter operators, pagination/cursor/distinct, select/include/omit, nested writes, relation filters, atomic number updates, JSON, Decimal/BigInt/DateTime, scalar arrays (pg), raw queries, and transactions. Zero adapter bugs — the MySQL gaps (mode:insensitive, createManyAndReturn, disconnect/set on required relations, scalar arrays) are standard Prisma-on-MySQL behavior, identical to the native mysql2 driver. Wired as opt-in scripts (test:int:orm:prisma:coverage[:pg|:mysql]) that generate their own client; the default test:int:orm:prisma stays lean.
CLAUDE.md is listed under the AI-instruction-files block in .gitignore but was still tracked, unlike WARP.md/.cursorrules/etc. Untrack it to match that policy; the file stays on disk locally.
9efbd59 to
62ad504
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This adds a Prisma driver adapter so you can run Prisma Client against the Aurora Data API, on both Postgres and MySQL. You import
createPrismaPgAdapter(or the MySQL one), hand it tonew PrismaClient({ adapter }), and Prisma talks to the Data API instead of opening its own connection.Prisma is the one ORM where our usual trick doesn't work. The
pg,mysql2, andknexlayers all pretend to be a Node driver and let the ORM callquery(). Prisma won't take an injected driver that way. Its query engine normally opens its own socket, so this uses Prisma's driver-adapter API instead. That's the same path Neon and PlanetScale use for their serverless drivers.The adapter stays thin. It holds a normal
init()client and reuses everything that already works: query sending, the scale-to-zero retry, result formatting, and the transaction methods. The only new code is the part Prisma actually needs.$1/?params into Data API params, and rewriting Postgres array params intoARRAY[...], since the Data API can't bind arrays directlyTwo small bugs in the core turned up while I wired this together, and both are fixed with tests. Arrays were getting flattened into the row under
hydrateColumnNames: false, and an explicit paramtypeHintwas getting dropped.What works
I ran the whole Prisma Client query API against both engines on a live cluster. That's 179 tests. CRUD, aggregation and groupBy, every filter operator, pagination and cursors, select/include/omit, nested writes, relation filters, atomic number updates, JSON, Decimal/BigInt/DateTime, scalar arrays on Postgres, raw queries, and transactions. All of it passes.
The only gaps on MySQL are the ones Prisma already has on MySQL:
mode: 'insensitive',createManyAndReturn, anddisconnect/seton a required relation. You'd hit those same walls with the realmysql2driver. None of it is specific to the Data API.Migrations
Driver adapters only cover the runtime query path. Prisma's schema engine (
migrate,db push,db pull) still wants a direct connection URL, and the Data API doesn't give you one. This is the same split Neon and PlanetScale have, where the adapter runs your queries and a direct URL runs your migrations.There are two ways to handle it, both in the README. Point Prisma's migration URL at the Aurora cluster endpoint, which is the one I'd recommend and matches Neon's
directUrl. Or generate the SQL offline withprisma migrate diffand apply it over the adapter.Test plan
npm run test-ci(lint, build, 179 unit tests)npm run test:int:orm:prisma(live pg + mysql suites, needs.env.local)npm run test:int:orm:prisma:coverage(the full API coverage audit, both engines)