diff --git a/content/200-orm/050-overview/500-databases/950-cloudflare-d1.mdx b/content/200-orm/050-overview/500-databases/950-cloudflare-d1.mdx index 4ce7183a19..015d716563 100644 --- a/content/200-orm/050-overview/500-databases/950-cloudflare-d1.mdx +++ b/content/200-orm/050-overview/500-databases/950-cloudflare-d1.mdx @@ -34,7 +34,7 @@ Many aspects of using Prisma ORM with D1 are just like using Prisma ORM with any There are a number of differences between D1 and SQLite to consider. You should be aware of the following when deciding to use D1 and Prisma ORM: -- **Making schema changes**. As of [v6.6.0](https://pris.ly/release/6.6.0) and with a `prisma.config.ts` file, you can use `prisma db push`. However, if you prefer a Cloudflare first approach, you can use D1's [migration system](https://developers.cloudflare.com/d1/reference/migrations/) and the [`prisma migrate diff`](/orm/reference/prisma-cli-reference#migrate-diff) command for your migration workflows. See the [Schema migrations with Prisma ORM on D1](#schema-migrations-with-prisma-orm-on-d1) section below for more information. +- **Making schema changes**. With Prisma ORM 7, you need to use D1's [migration system](https://developers.cloudflare.com/d1/reference/migrations/) via the Wrangler CLI combined with the [`prisma migrate diff`](/orm/reference/prisma-cli-reference#migrate-diff) command for your migration workflows. See the [Schema migrations with Prisma ORM on D1](#schema-migrations-with-prisma-orm-on-d1) section below for more information. - **Local and remote D1 (SQLite) databases**. Cloudflare provides local and remote versions of D1. The [local](https://developers.cloudflare.com/d1/build-with-d1/local-development/) version is managed using the `--local` option of the `wrangler d1` CLI and is located in `.wrangler/state`. The [remote](https://developers.cloudflare.com/d1/build-with-d1/remote-development/) version is managed by Cloudflare and is accessed via HTTP. ## How to connect to D1 in Cloudflare Workers or Cloudflare Pages @@ -45,106 +45,13 @@ If you want to deploy a Cloudflare Worker with D1 and Prisma ORM, follow these [ ## Schema migrations with Prisma ORM on D1 -You can use two approaches for migrating your database schema with Prisma ORM and D1: -- Using `prisma db push` via a driver adapter in `prisma.config.ts` -- Using the Wrangler CLI +With Prisma ORM 7, the recommended approach for managing database schema migrations with Cloudflare D1 is to use the Wrangler CLI combined with `prisma migrate diff`. -### Using Prisma Migrate via a driver adapter in Prisma Config +### Using the Wrangler CLI with `prisma migrate diff` -As of [Prisma v6.6.0](https://github.com/prisma/prisma/releases/tag/6.6.0) we added support for the Prisma Config file. You can use the Prisma Config file to perform `prisma db push` and make changes to your database schema. You can learn more about [the Prisma Config file in our reference page](/orm/reference/prisma-config-reference). +Cloudflare D1 comes with its own [migration system](https://developers.cloudflare.com/d1/reference/migrations/) that works via the `wrangler d1` CLI commands. -#### 1. Install the Prisma D1 driver adapter - -Run this command in your terminal: - -```terminal -npm install @prisma/adapter-d1 -``` - -#### 2. Set environment variables - -In order to set up the D1 adapter, you'll need to add a few secrets to a `.env` file: - -- `CLOUDFLARE_ACCOUNT_ID`: Your Cloudflare account ID, fetched via `npx wrangler whoami`. -- `CLOUDFLARE_DATABASE_ID`: Retrieved during D1 database creation. If you have an existing D1 database, you can use `npx wrangler d1 list` and `npx wrangler d1 info ` to get the ID. -- `CLOUDFLARE_D1_TOKEN`: This API token is used by Prisma ORM to communicate with your D1 instance directly. To create it, follow these steps: - 1. Visit https://dash.cloudflare.com/profile/api-tokens - 2. Click **Create Token** - 3. Click **Custom token** template - 4. Fill out the template: Make sure you use a recognizable name and add the **Account / D1 / Edit** permission. - 5. Click **Continue to summary** and then **Create Token**. - -You can then add these to your `.env` file or use them directly if they are stored in a different secret store: - -```bash file=.env -CLOUDFLARE_ACCOUNT_ID="0773..." -CLOUDFLARE_DATABASE_ID="01f30366-..." -CLOUDFLARE_D1_TOKEN="F8Cg..." -``` - -#### 3. Set up Prisma Config file - -Make sure that you have a [`prisma.config.ts`](/orm/reference/prisma-config-reference) file for your project. Then, set up the [migration driver adapter](/orm/reference/prisma-config-reference#adapter-removed) to reference D1: - -```ts file=prisma.config.ts -import type { PrismaConfig } from 'prisma'; -import { PrismaD1 } from '@prisma/adapter-d1'; - -// import your .env file -import 'dotenv/config'; - -export default { - // add-start - experimental: { - adapter: true, - }, - // add-end - schema: 'prisma/schema.prisma', - // add-start - async adapter() { - return new PrismaD1({ - CLOUDFLARE_D1_TOKEN: process.env.CLOUDFLARE_D1_TOKEN!, - CLOUDFLARE_ACCOUNT_ID: process.env.CLOUDFLARE_ACCOUNT_ID!, - CLOUDFLARE_DATABASE_ID: process.env.CLOUDFLARE_DATABASE_ID!, - }); - }, - // add-end -} satisfies PrismaConfig; -``` - -:::note - -As of [Prisma ORM v6.11.0](https://github.com/prisma/prisma/releases/tag/6.11.0), the D1 adapter has been renamed from `PrismaD1HTTP` to `PrismaD1`. - -::: - -#### 4. Migrate your database - -Prisma Migrate now will run migrations against your remote D1 database based on the configuration provided in `prisma.config.ts`. - -To update the remote schema with this workflow, run the following command: - -```terminal -npx prisma db push -``` - -:::note - -Note that for querying the database, you keep using the `PrismaD1` driver adapter from the `@prisma/adapter-d1` package: - -```ts -import { PrismaD1 } from '@prisma/adapter-d1' -``` - -::: - -### Using the Wrangler CLI - -Cloudflare D1 comes with its own [migration system](https://developers.cloudflare.com/d1/reference/migrations/). While we recommend that you use the [native Prisma Migrate workflow](#using-prisma-migrate-via-a-driver-adapter-in-prisma-config), this migration system via the `wrangler d1 migrations` command is available. - -This command doesn't help you in figuring out the SQL statements for creating your database schema that need to be put _inside_ of these migration files though. If you want to query your database using Prisma Client, it's important that your database schema maps to your Prisma schema, this is why it's recommended to generate the SQL statements from your Prisma schema. - -When using D1, you can use the [`prisma migrate diff`](/orm/reference/prisma-cli-reference#migrate-diff) command for that purpose. +The Wrangler CLI provides the structure for migrations, but you need to generate the SQL statements from your Prisma schema. This is where [`prisma migrate diff`](/orm/reference/prisma-cli-reference#migrate-diff) comes in - it generates SQL statements based on your Prisma schema that you can then apply using Wrangler. #### Creating an initial migration @@ -190,7 +97,7 @@ For the initial migration, you can use the special `--from-empty` option though: ```terminal npx prisma migrate diff \ --from-empty \ - --to-schema-datamodel ./prisma/schema.prisma \ + --to-schema ./prisma/schema.prisma \ --script \ --output migrations/0001_create_user_table.sql ``` @@ -198,7 +105,7 @@ npx prisma migrate diff \ The command above uses the following options: - `--from-empty`: The source for the SQL statement is an empty schema. -- `--to-schema-datamodel ./prisma/schema.prisma`: The target for the SQL statement is the data model in `./prisma/schema.prisma`. +- `--to-schema ./prisma/schema.prisma`: The target for the SQL statement is the schema in `./prisma/schema.prisma`. - `--script`: Output the result as SQL. If you omit this option, the "migration steps" will be generated in plain English. - `--output migrations/0001_create_user_table.sql`: Store the result in `migrations/0001_create_user_table.sql`. @@ -281,7 +188,7 @@ As explained above, you now need to use `--from-local-d1` instead of `--from-emp ```terminal npx prisma migrate diff \ --from-local-d1 \ - --to-schema-datamodel ./prisma/schema.prisma \ + --to-schema ./prisma/schema.prisma \ --script \ --output migrations/0002_create_post_table.sql ``` @@ -289,7 +196,7 @@ npx prisma migrate diff \ The command above uses the following options: - `--from-local-d1`: The source for the SQL statement is the local D1 database file. -- `--to-schema-datamodel ./prisma/schema.prisma`: The target for the SQL statement is the data model in `./prisma/schema.prisma`. +- `--to-schema ./prisma/schema.prisma`: The target for the SQL statement is the schema in `./prisma/schema.prisma`. - `--script`: Output the result as SQL. If you omit this option, the "migration steps" will be generated in plain English. - `--output migrations/0002_create_post_table.sql`: Store the result in `migrations/0002_create_post_table.sql`. @@ -325,8 +232,4 @@ npx wrangler d1 migrations apply __YOUR_DATABASE_NAME__ --remote ### Transactions not supported -Cloudflare D1 currently does not support transactions (see the [open feature request](https://github.com/cloudflare/workers-sdk/issues/2733)). As a result, Prisma ORM does not support transactions for Cloudflare D1. When using Prisma's D1 adapter, implicit & explicit transactions will be ignored and run as individual queries, which breaks the guarantees of the ACID properties of transactions. - -### Prisma Migrate only supports remote D1 databases - -The Wrangler CLI can distinguish between local and remote D1 (i.e. SQLite) database instances via the `--local` and `--remote` options. This distinction is currently not available with the [native Prisma Migrate workflow](#using-prisma-migrate-via-a-driver-adapter-in-prisma-config). \ No newline at end of file +Cloudflare D1 currently does not support transactions (see the [open feature request](https://github.com/cloudflare/workers-sdk/issues/2733)). As a result, Prisma ORM does not support transactions for Cloudflare D1. When using Prisma's D1 adapter, implicit & explicit transactions will be ignored and run as individual queries, which breaks the guarantees of the ACID properties of transactions. \ No newline at end of file diff --git a/content/800-guides/070-cloudflare-d1.mdx b/content/800-guides/070-cloudflare-d1.mdx index 5cd25c94cc..017e638d21 100644 --- a/content/800-guides/070-cloudflare-d1.mdx +++ b/content/800-guides/070-cloudflare-d1.mdx @@ -49,12 +49,13 @@ npm install --save-dev prisma ## 2. Configure Prisma schema -In your Prisma schema, set the `provider` of the `datasource` to `sqlite`. If you just bootstrapped the Prisma schema with `prisma init`, also be sure to add the following `User` model to it: +In your Prisma schema, set the `provider` of the `datasource` to `sqlite`. If you just bootstrapped the Prisma schema with `prisma init`, also be sure to add the `runtime = "cloudflare"` to the generator block and the following `User` model: ```prisma file=prisma/schema.prisma generator client { provider = "prisma-client" output = "../src/generated/prisma" + runtime = "cloudflare" } datasource db { @@ -75,7 +76,7 @@ model User { Next, install the required packages: ```terminal -npm install @prisma/adapter-d1 dotenv +npm install @prisma/client @prisma/adapter-d1 dotenv ``` Also, be sure to use a version of the Wrangler CLI that's above [`wrangler@^3.39.0`](https://github.com/cloudflare/workers-sdk/releases/tag/wrangler%403.39.0), otherwise the `--remote` flag that's used in the next sections won't be available. @@ -143,98 +144,98 @@ If you weren't able to grab the database ID from the terminal output, you can al ## 5. Set up database migrations -:::note +For Cloudflare D1, you'll use Prisma's migration workflow combined with Wrangler CLI to manage your database schema. Since D1 is a serverless SQLite database, we'll use `prisma migrate diff` to generate migration SQL and then apply it using Wrangler. -We recommend using `prisma migrate` in order to keep your data in D1 migrated. However, if you would prefer to use Cloudflare's migration system, [that workflow is also available](/orm/overview/databases/cloudflare-d1#using-the-wrangler-cli) +### 5.1 Set up environment variables -::: +Add a `.env` file in the root of your project with your local database URL: -### 5.1 Add needed environment variables +```bash file=.env +DATABASE_URL="file:./prisma/db.sqlite" +``` -In order to use the Prisma D1 adapter, you'll need to add a few secrets to a `.env` file: -- `DATABASE_URL`: A path to your local D1 instance. Usually `"file:./prisma/db.sqlite"`. -- `CLOUDFLARE_ACCOUNT_ID`: Your Cloudflare account ID, fetched via `npx wrangler whoami` -- `CLOUDFLARE_DATABASE_ID`: The ID of your database, retrieved [during D1 database creation](#4-create-a-d1-database). -- `CLOUDFLARE_D1_TOKEN`: This API token is used by Prisma ORM to communicate with your D1 instance directly. To create this, follow these steps: - 1. Visit https://dash.cloudflare.com/profile/api-tokens - 2. Click "Create Token" - 3. On the *Custom token* section click on "Get started". - 4. Fill out the template: Make sure you use a recognizable name - 5. For the Permissions, add the `Account / D1 / Edit` permission. - 6. Click "Continue to summary" and then "Create Token". - 7. Click on "Copy" and store the token in a safe place. +Also create a `prisma.config.ts` file in the root of your project: -You can now store these secrets to be used by Prisma ORM. We recommend a `.env` file for local development, but any secret store will work. +```typescript file=prisma.config.ts +import 'dotenv/config'; +import { defineConfig, env } from 'prisma/config'; + +export default defineConfig({ + schema: 'prisma/schema.prisma', + migrations: { + path: 'prisma/migrations', + }, + datasource: { + url: env('DATABASE_URL'), + }, +}); +``` -```bash file=.env -DATABASE_URL="file:./prisma/db.sqlite" +### 5.2 Generate migration SQL + +First, create a migrations directory inside the `prisma` folder and create a file named `0001_init.sql`: -CLOUDFLARE_ACCOUNT_ID="0773..." -CLOUDFLARE_DATABASE_ID="01f30366-..." -CLOUDFLARE_D1_TOKEN="F8Cg..." +```terminal +mkdir -p prisma/migrations ``` -### 5.2 Configure Prisma Config +Now use `prisma migrate diff` to generate the SQL needed to create your database schema: -Ensure that you have a `prisma.config.ts` file set up in the root of your project with a [driver adapter](/orm/reference/prisma-config-reference#adapter-removed) defined. +```terminal +npx prisma migrate diff \ + --from-empty \ + --to-schema prisma/schema.prisma \ + --script > prisma/migrations/0001_init.sql +``` -```typescript file=prisma.config.ts -import type { PrismaConfig } from 'prisma'; -import { PrismaD1 } from '@prisma/adapter-d1'; +This command generates a SQL file that contains the statements needed to create your database tables. You can inspect the generated SQL in `prisma/migrations/0001_init.sql`. -// import your .env file -import 'dotenv/config'; +### 5.3 Apply migrations to D1 -export default { - experimental: { - adapter: true, - }, - schema: 'prisma/schema.prisma', - migrations: { - path: 'prisma/migrations', - }, - datasource: { - url: process.env.DATABASE_URL!, - }, - async adapter() { - return new PrismaD1({ - CLOUDFLARE_D1_TOKEN: process.env.CLOUDFLARE_D1_TOKEN!, - CLOUDFLARE_ACCOUNT_ID: process.env.CLOUDFLARE_ACCOUNT_ID!, - CLOUDFLARE_DATABASE_ID: process.env.CLOUDFLARE_DATABASE_ID!, - }); - }, -} satisfies PrismaConfig; +Now apply the migration to both your local and remote D1 databases using Wrangler: + +```terminal +# Apply to local database +npx wrangler d1 execute __YOUR_D1_DATABASE_NAME__ --local --file=./prisma/migrations/0001_init.sql + +# Apply to remote database +npx wrangler d1 execute __YOUR_D1_DATABASE_NAME__ --remote --file=./prisma/migrations/0001_init.sql ``` :::note -As of [Prisma ORM v6.11.0](https://github.com/prisma/prisma/releases/tag/6.11.0), the D1 adapter has been renamed from `PrismaD1HTTP` to `PrismaD1`. +Replace `__YOUR_D1_DATABASE_NAME__` with the actual name of your D1 database that you created in step 4. ::: -This will allow `prisma migrate` to interact with your D1 database. +### 5.4 Add sample data -### 4.3 Run your first migration - -You can now run `prisma migrate dev` to migrate your database to match your local schema: +Let's create some dummy data that we can query once the Worker is running: ```terminal -npx prisma migrate dev --name init +# For the local database +npx wrangler d1 execute __YOUR_D1_DATABASE_NAME__ --command "INSERT INTO \"User\" (\"email\", \"name\") VALUES ('jane@prisma.io', 'Jane Doe (Local)');" --local + +# For the remote database +npx wrangler d1 execute __YOUR_D1_DATABASE_NAME__ --command "INSERT INTO \"User\" (\"email\", \"name\") VALUES ('jane@prisma.io', 'Jane Doe (Remote)');" --remote ``` -Let's also create some dummy data that we can query once the Worker is running. This time, we'll use wrangler to run a SQL statement without storing it in a file: +:::info -```terminal -# For the local database -npx wrangler d1 execute __YOUR_D1_DATABASE_NAME__ --command "INSERT INTO \"User\" (\"email\", \"name\") VALUES -('jane@prisma.io', 'Jane Doe (Local)');" --local +For future schema changes, you can generate new migration files using: -# For the remote database -npx wrangler d1 execute __YOUR_D1_DATABASE_NAME__ --command "INSERT INTO \"User\" (\"email\", \"name\") VALUES -('jane@prisma.io', 'Jane Doe (Remote)');" --remote +```terminal +npx prisma migrate diff \ + --from-local-d1 \ + --to-schema-datamodel prisma/schema.prisma \ + --script > migrations/0002_add_new_field.sql ``` -## 5. Implement the Worker +Then apply them using the same `wrangler d1 execute` commands as shown above. + +::: + +## 6. Implement the Worker Before adding a Prisma Client query to your Worker, you need to generate Prisma Client with the following command: @@ -244,8 +245,8 @@ npx prisma generate In order to query your database from the Worker using Prisma ORM, you need to: -1. Add the `DB` binding to the `Env` interface. (Alternatively, you can run [`npx wrangler types`](https://developers.cloudflare.com/workers/wrangler/commands/#types) to generate the `Env` type from the binding in a separate file called `worker-configuration.d.ts`.) -2. Instantiate `PrismaClient` using the `PrismaD1` driver adapter. +1. Add the `DB` binding to the `Env` interface. This `DB` name matches the binding name you configured in `wrangler.jsonc`. (Alternatively, you can run [`npx wrangler types`](https://developers.cloudflare.com/workers/wrangler/commands/#types) to generate the `Env` type from the binding in a separate file called `worker-configuration.d.ts`.) +2. Instantiate `PrismaClient` using the `PrismaD1` driver adapter, passing `env.DB` which accesses your D1 database binding. 3. Send a query using Prisma Client and return the result. Open `src/index.ts` and replace the entire content with the following: @@ -270,15 +271,13 @@ export default { }; ``` -## 6. Run the Worker locally +## 7. Run the Worker locally -First copy the contents of your `.env` file to a new file called `.dev.vars` in the root of your project. This file will be used to set environment variables when running the Worker locally. +With the database query in place and Prisma Client generated, you can run the Worker locally. -```bash -cp .env .dev.vars -``` +If your Worker needs any environment variables, create a `.dev.vars` file in the root of your project. For this example, we don't need any additional environment variables since the D1 binding is already configured in `wrangler.jsonc`. -With the database query in place and Prisma Client generated, you can go ahead and run the Worker locally: +Now run the Worker locally: ``` npm run dev @@ -290,21 +289,15 @@ Now you can open your browser at [`http://localhost:8787`](http://localhost:8787 ;[{ id: 1, email: 'jane@prisma.io', name: 'Jane Doe (Local)' }] ``` -## 7. Set the `DATABASE_URL` environment variable and deploy the Worker +## 8. Deploy the Worker -To deploy the Worker, run the the following command: +To deploy the Worker, run the following command: ``` npm run deploy ``` -:::note - -Make sure to [upload the `.dev.vars` file to your Cloudflare Worker environment](https://developers.cloudflare.com/workers/configuration/secrets/#adding-secrets-to-your-project). This file contains the `DATABASE_URL` and other environment variables needed for the Worker to connect to the D1 database. - -::: - -Your deployed Worker is accessible via `https://prisma-d1-example.USERNAME.workers.dev`. If you navigate your browser to that URL, you should see the following data that's queried from your remote D1 database: +Your deployed Worker is accessible via `https://d1-tutorial.USERNAME.workers.dev` (replace `USERNAME` with your Cloudflare account username). If you navigate your browser to that URL, you should see the following data that's queried from your remote D1 database: ```js no-copy ;[{ id: 1, email: 'jane@prisma.io', name: 'Jane Doe (Remote)' }]