| 1 | --- |
| 2 | title: Drizzle Postgres on Prisma Compute |
| 3 | description: Use Alchemy's Prisma hosting provider to run a Drizzle API against Prisma Postgres. |
| 4 | --- |
| 5 | |
| 6 | Prisma here means Alchemy's Prisma hosting and database provider, not Prisma ORM. Complete [Prisma setup](/prisma/setup), start from the [prisma-compute-effect example](https://github.com/alchemy-run/alchemy/tree/main/examples/prisma-compute-effect), and add a `src/schema.ts` exporting `Users` from the [Postgres client guide](/sql/drizzle/postgres). |
| 7 | |
| 8 | ## Install the database dependencies |
| 9 | |
| 10 | ```sh |
| 11 | pnpm add drizzle-orm@1.0.0-rc.5-ab785fc @effect/sql-pg pg |
| 12 | pnpm add -D drizzle-kit@1.0.0-rc.5-ab785fc |
| 13 | ``` |
| 14 | |
| 15 | The Drizzle versions match the repository's Effect integration. |
| 16 | |
| 17 | ## Configure migrations |
| 18 | |
| 19 | ```typescript |
| 20 | // drizzle.config.ts |
| 21 | import { defineConfig } from "drizzle-kit"; |
| 22 | |
| 23 | export default defineConfig({ |
| 24 | dialect: "postgresql", |
| 25 | schema: "./src/schema.ts", |
| 26 | out: "./drizzle", |
| 27 | dbCredentials: { url: process.env.DATABASE_URL! }, |
| 28 | }); |
| 29 | ``` |
| 30 | |
| 31 | The migration runner needs the direct Postgres connection URL, not an Accelerate URL. |
| 32 | |
| 33 | ## Generate after changing the schema |
| 34 | |
| 35 | ```sh |
| 36 | pnpm exec drizzle-kit generate |
| 37 | ``` |
| 38 | |
| 39 | Review the generated SQL and snapshots, including any rename decisions, before applying them. |
| 40 | |
| 41 | ## Commit the migration |
| 42 | |
| 43 | ```sh |
| 44 | git add src/schema.ts drizzle.config.ts drizzle |
| 45 | git diff --cached |
| 46 | ``` |
| 47 | |
| 48 | ```sh |
| 49 | git commit -m "Add users migration" |
| 50 | ``` |
| 51 | |
| 52 | Commit the schema, SQL, and snapshots together; deployment consumes this reviewed history. |
| 53 | |
| 54 | ## Keep the standalone database |
| 55 | |
| 56 | The starter's `src/Database.ts` creates an explicit [Prisma Postgres database](/prisma/data/postgres) rather than relying on the project's default database: |
| 57 | |
| 58 | ```typescript |
| 59 | export const Postgres = Prisma.Postgres( |
| 60 | "Postgres", |
| 61 | Effect.gen(function* () { |
| 62 | const project = yield* Project; |
| 63 | return { project, region, branchGitName: "main" }; |
| 64 | }), |
| 65 | ); |
| 66 | ``` |
| 67 | |
| 68 | Keep `createDatabase: false` on `Project`, and use the same project and branch for Compute. |
| 69 | |
| 70 | ## Keep the connection resource |
| 71 | |
| 72 | ```typescript |
| 73 | export const Connection = Prisma.Connection( |
| 74 | "Connection", |
| 75 | Effect.gen(function* () { |
| 76 | const postgres = yield* Postgres; |
| 77 | return { database: postgres, name: "api" }; |
| 78 | }), |
| 79 | ); |
| 80 | ``` |
| 81 | |
| 82 | This is the starter's [connection resource](/prisma/data/connections); its redacted outputs include direct and pooled URLs when available. |
| 83 | |
| 84 | ## Keep the Compute binding |
| 85 | |
| 86 | ```typescript |
| 87 | // Inside the runtime Effect in src/Api.ts |
| 88 | const db = yield* Prisma.Connect(Connection); |
| 89 | ``` |
| 90 | |
| 91 | ```typescript |
| 92 | // On that runtime Effect |
| 93 | .pipe(Effect.provide(Prisma.ConnectBinding)) |
| 94 | ``` |
| 95 | |
| 96 | `Prisma.Compute<Api>()` uses `main: import.meta.filename` and binds connection values into its environment. `db.databaseUrl` is the connection Effect to pass to Drizzle, not a SQL execution method. |
| 97 | |
| 98 | ## Provision before the first migration |
| 99 | |
| 100 | ```sh |
| 101 | pnpm alchemy deploy |
| 102 | ``` |
| 103 | |
| 104 | Keep the starter's `Prisma.providers()`, `yield* Api`, and `/api/health` handler for this initial deployment. Its connection-binding check does not query application tables. |
| 105 | |
| 106 | ## Apply the committed SQL |
| 107 | |
| 108 | ```sh |
| 109 | pnpm exec drizzle-kit migrate |
| 110 | ``` |
| 111 | |
| 112 | Supply the connection resource's `directConnectionString` output as the migration runner's secret `DATABASE_URL`; it must contain a PostgreSQL URL, not be absent or Accelerate-only. `Prisma.Postgres` has no production `migrations` prop, and `dev.migrate` only runs against the local development database. |
| 113 | |
| 114 | ## Open the Drizzle client |
| 115 | |
| 116 | ```diff lang="typescript" |
| 117 | // src/Api.ts |
| 118 | +import * as Drizzle from "alchemy/Drizzle/Postgres"; |
| 119 | |
| 120 | const db = yield* Prisma.Connect(Connection); |
| 121 | +const database = yield* Drizzle.Postgres(db.databaseUrl); |
| 122 | ``` |
| 123 | |
| 124 | `databaseUrl` prefers pooled Postgres and then direct Postgres; use a connection that actually has one of those URLs, since Drizzle's `pg` driver cannot use an Accelerate-only fallback. |
| 125 | |
| 126 | ## Query from Compute |
| 127 | |
| 128 | Import `Users` from `./schema.ts` and replace the starter's `fetch` handler: |
| 129 | |
| 130 | ```typescript |
| 131 | fetch: Effect.gen(function* () { |
| 132 | const request = yield* HttpServerRequest; |
| 133 | const path = new URL(request.url, "http://localhost").pathname; |
| 134 | if (path === "/api/health") { |
| 135 | return yield* HttpServerResponse.json({ ok: true }); |
| 136 | } |
| 137 | const users = yield* database.select().from(Users).pipe(Effect.orDie); |
| 138 | return yield* HttpServerResponse.json({ users }); |
| 139 | }), |
| 140 | ``` |
| 141 | |
| 142 | Keep the existing `healthCheck: { path: "/api/health" }`; application queries now run within the request scope. |
| 143 | |
| 144 | ## Deploy and exercise the query |
| 145 | |
| 146 | ```sh |
| 147 | pnpm alchemy deploy |
| 148 | curl "$API_URL/" |
| 149 | ``` |
| 150 | |
| 151 | Set `API_URL` to the Stack's `url` output and verify the query response, not just `/api/health`. For later changes, generate, review, and commit first, then apply migrations and deploy compatible code; `alchemy deploy` does not replace `drizzle-kit migrate`. |
| 152 | |
| 153 | ## Continue |
| 154 | |
| 155 | See the [Prisma Postgres guide](/prisma/data/postgres), [Compute deployment guide](/prisma/compute/apps), [portable Postgres queries](/sql/drizzle/postgres), and [migration workflow](/sql/drizzle/migrations). The [Prisma tutorial example](https://github.com/alchemy-run/alchemy/tree/main/examples/prisma-tutorial) exercises the same Postgres driver through `SQL.Postgres` in Compute. |