From fcd00ac58bef341fc728db06aa38f03e179e2635 Mon Sep 17 00:00:00 2001 From: Nikolas Date: Tue, 2 Apr 2024 16:11:04 +0200 Subject: [PATCH] d1 docs (#5746) * d1 instructions in cf workers deployment docs * add notes about d1 to driver adapters docs * add D1 to supported DBs * Update content/200-orm/050-overview/500-databases/950-cloudflare-d1.mdx * Update content/200-orm/200-prisma-client/500-deployment/301-edge/450-deploy-to-cloudflare.mdx * Update content/200-orm/050-overview/500-databases/200-database-drivers.mdx Co-authored-by: Jan Piotrowski * Update content/200-orm/050-overview/500-databases/200-database-drivers.mdx Co-authored-by: Jan Piotrowski * continue d1 docs * continue d1 docs * continue d1 docs * Update content/200-orm/200-prisma-client/500-deployment/301-edge/450-deploy-to-cloudflare.mdx * Update content/200-orm/200-prisma-client/500-deployment/301-edge/450-deploy-to-cloudflare.mdx * Update content/200-orm/200-prisma-client/500-deployment/301-edge/450-deploy-to-cloudflare.mdx Co-authored-by: Jan Piotrowski * add info about migration workflows * add info about migration workflows * fix typo * update d1 docs * update d1 docs * Update content/200-orm/200-prisma-client/500-deployment/301-edge/450-deploy-to-cloudflare.mdx Co-authored-by: Jan Piotrowski * add notes about bootstrapping a project * add link to feedback discussion * update instructions for d1 * Update content/200-orm/200-prisma-client/500-deployment/301-edge/450-deploy-to-cloudflare.mdx Co-authored-by: Alberto Schiabel * update instructions for d1 * update instructions for d1 * update instructions for d1 to use --from-local-d1 * Update content/200-orm/050-overview/500-databases/950-cloudflare-d1.mdx Co-authored-by: Alberto Schiabel * fix typos --------- Co-authored-by: Jan Piotrowski Co-authored-by: Jon Harrell <4829245+jharrell@users.noreply.github.com> Co-authored-by: Alberto Schiabel --- cSpell.json | 1 + .../500-databases/200-database-drivers.mdx | 3 + .../500-databases/850-planetscale.mdx | 4 +- .../500-databases/950-cloudflare-d1.mdx | 252 ++++++++++++++++++ .../500-deployment/301-edge/100-overview.mdx | 2 + .../301-edge/450-deploy-to-cloudflare.mdx | 208 ++++++++++++++- .../301-edge/485-deploy-to-vercel.mdx | 6 + .../500-reference/375-supported-databases.mdx | 1 + content/300-accelerate/650-troubleshoot.mdx | 2 +- 9 files changed, 473 insertions(+), 6 deletions(-) create mode 100644 content/200-orm/050-overview/500-databases/950-cloudflare-d1.mdx diff --git a/cSpell.json b/cSpell.json index 4bf3df6f3f..a414d24793 100644 --- a/cSpell.json +++ b/cSpell.json @@ -27,6 +27,7 @@ "MSSQLSERVER", "neovim", "Nestjs", + "Overfetching", "pgbouncer", "planetscale", "pooler", diff --git a/content/200-orm/050-overview/500-databases/200-database-drivers.mdx b/content/200-orm/050-overview/500-databases/200-database-drivers.mdx index 6998d325bf..b378df7156 100644 --- a/content/200-orm/050-overview/500-databases/200-database-drivers.mdx +++ b/content/200-orm/050-overview/500-databases/200-database-drivers.mdx @@ -41,6 +41,7 @@ Prisma ORM maintains the following serverless driver adapters: - [Neon](/orm/overview/databases/neon#how-to-use-neons-serverless-driver-with-prisma-orm-preview) - [PlanetScale](/orm/overview/databases/planetscale#how-to-use-the-planetscale-serverless-driver-with-prisma-orm-preview) +- [Cloudflare D1](orm/overview/databases/cloudflare-d1) ### Community-maintained database driver adapters @@ -69,9 +70,11 @@ To use this feature: 3. Refer to the following pages to learn more how to use the specific driver adapters with the specific database providers: + - [PostgreSQL](/orm/overview/databases/postgresql#using-the-node-postgres-driver) - [Neon](/orm/overview/databases/neon#how-to-use-neons-serverless-driver-with-prisma-orm-preview) - [PlanetScale](/orm/overview/databases/planetscale#how-to-use-the-planetscale-serverless-driver-with-prisma-orm-preview) - [Turso](/orm/overview/databases/turso#how-to-connect-and-query-a-turso-database) + - [Cloudflare D1](/orm/overview/databases/cloudflare-d1) ## Notes about using driver adapters diff --git a/content/200-orm/050-overview/500-databases/850-planetscale.mdx b/content/200-orm/050-overview/500-databases/850-planetscale.mdx index 6cd9bda929..e2fedb9871 100644 --- a/content/200-orm/050-overview/500-databases/850-planetscale.mdx +++ b/content/200-orm/050-overview/500-databases/850-planetscale.mdx @@ -38,7 +38,7 @@ PlanetScale's branching model and design for scalability means that there are al - **Branching and deploy requests.** PlanetScale provides two types of database branches: _development branches_, which allow you to test out schema changes, and _production branches_, which are protected from direct schema changes. Instead, changes must be first created on a development branch and then deployed to production using a deploy request. Production branches are highly available and include automated daily backups. To learn more, see [How to use branches and deploy requests](#how-to-use-branches-and-deploy-requests). - **Referential actions and integrity.** To support scaling across multiple database servers, PlanetScale [by default does not use foreign key constraints](https://planetscale.com/docs/learn/operating-without-foreign-key-constraints), which are normally used in relational databases to enforce relationships between data in different tables, and asks users to handle this manually in their applications. However, you can explicitly [enable them in the PlanetScale database settings](https://planetscale.com/docs/concepts/foreign-key-constraints). If you don't enable these explicitly, you can still maintain these relationships in your data and allow the use of [referential actions](/orm/prisma-schema/data-model/relations/referential-actions) by using Prisma ORM's ability to [emulate relations in Prisma Client](/orm/prisma-schema/data-model/relations/relation-mode#emulate-relations-in-prisma-orm-with-the-prisma-relation-mode) with the `prisma` relation mode. For more information, see [How to emulate relations in Prisma Client](#option-1-emulate-relations-in-prisma-client). -- **Creating indexes on foreign keys.** When [emulating relations in Prisma ORM](#option-1-emulate-relations-in-prisma-client) (i.e. when _not_ using foreign key constraints on the database-level), you will need to create dedicated indexes on foreign keys. In a standard MySQL database, if a table has a column with a foreign key constraint, an index is automatically created on that column. When PlanetScale is configured to not use foreign key constraints, these indexes are [currently](https://github.com/prisma/prisma/issues/10611) not created when Prisma Client emulates relations, which can lead to issues with queries not being well optimised. To avoid this, you can create indexes in Prisma ORM. For more information, see [How to create indexes on foreign keys](#2-create-indexes-on-foreign-keys). +- **Creating indexes on foreign keys.** When [emulating relations in Prisma ORM](#option-1-emulate-relations-in-prisma-client) (i.e. when _not_ using foreign key constraints on the database-level), you will need to create dedicated indexes on foreign keys. In a standard MySQL database, if a table has a column with a foreign key constraint, an index is automatically created on that column. When PlanetScale is configured to not use foreign key constraints, these indexes are [currently](https://github.com/prisma/prisma/issues/10611) not created when Prisma Client emulates relations, which can lead to issues with queries not being well optimized. To avoid this, you can create indexes in Prisma ORM. For more information, see [How to create indexes on foreign keys](#2-create-indexes-on-foreign-keys). - **Making schema changes with `db push`.** When you merge a development branch into your production branch, PlanetScale will automatically compare the two schemas and generate its own schema diff. This means that Prisma ORM's [`prisma migrate`](/orm/prisma-migrate) workflow, which generates its own history of migration files, is not a natural fit when working with PlanetScale. These migration files may not reflect the actual schema changes run by PlanetScale when the branch is merged. @@ -108,7 +108,7 @@ model Comment { } ``` -The `postId` field in the `Comment` model refers to the corresponding `id` field in the `Post` model. However this is not implemented as a foreign key in PlanetScale, so the column doesn't have an automatic index. This means that some queries may not be well optimised. For example, if you query for all comments with a certain post `id`, PlanetScale may have to do a full table lookup. This could be slow, and also expensive because PlanetScale's billing model charges for the number of rows read. +The `postId` field in the `Comment` model refers to the corresponding `id` field in the `Post` model. However this is not implemented as a foreign key in PlanetScale, so the column doesn't have an automatic index. This means that some queries may not be well optimized. For example, if you query for all comments with a certain post `id`, PlanetScale may have to do a full table lookup. This could be slow, and also expensive because PlanetScale's billing model charges for the number of rows read. To avoid this, you can define an index on the `postId` field using [Prisma ORM's `@@index` argument](/orm/reference/prisma-schema-reference#index): 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 new file mode 100644 index 0000000000..cce762ef8c --- /dev/null +++ b/content/200-orm/050-overview/500-databases/950-cloudflare-d1.mdx @@ -0,0 +1,252 @@ +--- +title: 'Cloudflare D1' +metaTitle: 'Cloudflare D1' +metaDescription: 'Guide to Cloudflare D1' +tocDepth: 3 +preview: true +--- + + + +This guide discusses the concepts behind using Prisma ORM and Cloudflare D1, explains the commonalities and differences between Cloudflare D1 and other database providers, and leads you through the process for configuring your application to integrate with Cloudflare D1. + +Prisma ORM support for Cloudflare D1 is currently in [Preview](/orm/more/releases#preview). We would appreciate your feedback [on GitHub](https://github.com/prisma/prisma/discussions/23646). + + + +## What is Cloudflare D1? + +D1 is Cloudflare's native serverless database and was initially [launched in 2022](https://blog.cloudflare.com/introducing-d1). It's based on SQLite and can be used when deploying applications with Cloudflare. D1 . + +Following Cloudflare's principles of geographic distribution and bringing compute and data closer to application users, D1 supports automatic read-replication. It dynamically manages the number of database instances and locations of read-only replicas based on how many queries a database is getting, and from where. + +For write-operations, queries travel to a single primary instance in order to propagate the changes to all read-replicas and ensure data consistency. + +## Commonalities with other database providers + +D1 is based on SQLite. + +Many aspects of using Prisma ORM with D1 are just like using Prisma ORM with any other relational database. You can still: + +- model your database with the [Prisma Schema Language](/orm/prisma-schema) +- use Prisma ORM's existing [`sqlite` database connector](/orm/overview/databases/sqlite) in your schema +- use [Prisma Client](/orm/prisma-client) in your application to talk to the database server at D1 + +## Differences to consider + +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: + +- **Local and remote D1 (SQLite) databases**. Cloudflare provides local and remote versions of D1. The [local](https://developers.cloudflare.com/d1/configuration/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/configuration/remote-development) version is managed by Cloudflare and is accessed via HTTP. +- **Making schema changes**. Since D1 uses HTTP to connect to the remote database, this makes it incompatible with some commands of Prisma Migrate, like `prisma migrate dev`. However, 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 [Migration workflows](#migration-workflows) below for more information. + +## How to connect to D1 in Cloudflare Workers or Cloudflare pages + +When using Prisma ORM with D1, you need to use the `sqlite` database provider and the `@prisma/adapter-d1` [driver adapter](/orm/overview/databases/database-drivers#driver-adapters). + +If you want to deploy a Cloudflare Worker with D1 and Prisma ORM, follow these [step-by-step instructions](/orm/prisma-client/deployment/edge/deploy-to-cloudflare#d1). + +## Migration workflows + +Cloudflare D1 comes with its own [migration system](https://developers.cloudflare.com/d1/reference/migrations/). We recommend that you use this migration system via the `wrangler d1 migrations` command to create and manage migration files on your file system. + +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 generated 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. + +### Creating an initial migration + +The workflow for creating an initial migration looks as follows. Assume you have a fresh D1 instance without any tables. + +#### 1. Update your Prisma data model + +This is your initial version of the Prisma schema that you want to map to your D1 instance: + +```prisma +model User { + id Int @id @default(autoincrement()) + email String @unique + name String? +} +``` + +#### 2. Create migration file using `wrangler` CLI + +Next, you need to create the migration file using the [`wrangler d1 migrations create`](https://developers.cloudflare.com/workers/wrangler/commands/#migrations-create) command: + +```terminal +npx wrangler d1 migrations create __YOUR_DATABASE_NAME__ create_user_table +``` + +Since this is the very first migration, this command will prompt you to also create a `migrations` folder. Note that if you want your migration files to be stored in a different location, you can [customize it using Wrangler](https://developers.cloudflare.com/d1/reference/migrations/#wrangler-customizations). + +Once the command has executed and assuming you have chosen the default `migrations` name for the location of your migration files, the command has created the following folder and file for you: + +```no-copy +migrations/ +└── 0001_create_user_table.sql +``` + +However, before you can apply the migration to your D1 instance, you actually need to put a SQL statement into the currently empty `0001_create_user_table.sql` file. + +#### 3. Generate SQL statements using `prisma migrate diff` + +To generate the initial SQL statement, you can use the `prisma migrate diff` command which compares to _schemas_ (via its `--to-X` and `--from-X` options) and generates the steps that are needed to "evolve" from one to the other. These schemas can be either Prisma or SQL schemas. + +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 \ + --script > migrations/0001_create_user_table.sql +``` + +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`. +- `--script`: Output the result as SQL. If you omit this option, the "migration steps" will be generated in plain English. +- `> migrations/0001_create_user_table.sql`: Store the result in `migrations/0001_create_user_table.sql`. + +After running this command, `migrations/0001_create_user_table.sql` will have the following contents: + +```sql file=migrations/0001_create_user_table.sql no-copy +-- CreateTable +CREATE TABLE "User" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "email" TEXT NOT NULL, + "name" TEXT +); + +-- CreateIndex +CREATE UNIQUE INDEX "User_email_key" ON "User"("email"); +``` + +#### 4. Execute the migration using `wrangler d1 migrations apply` + +Finally, you can apply the migration against your D1 instances. + +For the **local** instance, run: + +```terminal +npx wrangler d1 migrations apply __YOUR_DATABASE_NAME__ --local +``` + +For the **remote** instance, run: + +```terminal +npx wrangler d1 migrations apply __YOUR_DATABASE_NAME__ --remote +``` + +### Evolve your schema with further migrations + +For any further migrations, you can use the same workflow but instead of using `--from-empty`, you'll need to use `--from-local-d1` because your source schema for the `prisma migrate diff` command now is the current schema of that local D1 instance, while the target remains your (then updated) Prisma schema. + + + + + +#### 1. Update your Prisma data model + +Assume you have updated your Prisma schema with another model: + +```prisma +model User { + id Int @id @default(autoincrement()) + email String @unique + name String? + posts Post[] +} + +model Post { + id Int @id @default(autoincrement()) + title String + author User @relation(fields: [authorId], references: [id]) + authorId Int +} +``` + +#### 2. Create migration file using `wrangler` CLI + +Like before, you first need to create the migration file: + +```terminal +npx wrangler d1 migrations create __YOUR_DATABASE_NAME__ create_post_table +``` + +Once the command has executed (again assuming you have chosen the default `migrations` name for the location of your migration files), the command has created a new file inside of the `migrations` folder: + +```no-copy +migrations/ +├── 0001_create_user_table.sql +└── 0002_create_post_table.sql +``` + +As before, you now need to put a SQL statement into the currently empty `0002_create_post_table.sql` file. + +#### 3. Generate SQL statements using `prisma migrate diff` + +As explained above, you now need to use `--from-local-d1` instead of `--from-empty` to specify a source schema: + +```terminal +npx prisma migrate diff \ + --from-local-d1 \ + --to-schema-datamodel ./prisma/schema.prisma \ + --script > migrations/0002_create_post_table.sql +``` + + + +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`. +- `--script`: Output the result as SQL. If you omit this option, the "migration steps" will be generated in plain English. +- `> migrations/0002_create_post_table.sql`: Store the result in `migrations/0002_create_post_table.sql`. + +After running this command, `migrations/0002_create_post_table.sql` will have the following contents: + +```sql file=migrations/0002_create_post_table.sql no-copy +-- CreateTable +CREATE TABLE "Post" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "title" TEXT NOT NULL, + "authorId" INTEGER NOT NULL, + CONSTRAINT "Post_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "User" ("id") ON DELETE RESTRICT ON UPDATE CASCADE +); +``` + +#### 4. Execute the migration using `wrangler d1 migrations apply` + +Finally, you can apply the migration against your D1 instances. + +For the **local** instance, run: + +```terminal +npx wrangler d1 migrations apply __YOUR_DATABASE_NAME__ --local +``` + +For the **remote** instance, run: + +```terminal +npx wrangler d1 migrations apply __YOUR_DATABASE_NAME__ --remote +``` diff --git a/content/200-orm/200-prisma-client/500-deployment/301-edge/100-overview.mdx b/content/200-orm/200-prisma-client/500-deployment/301-edge/100-overview.mdx index 6d152f79f9..26ca8b08cf 100644 --- a/content/200-orm/200-prisma-client/500-deployment/301-edge/100-overview.mdx +++ b/content/200-orm/200-prisma-client/500-deployment/301-edge/100-overview.mdx @@ -39,6 +39,7 @@ Here is an overview of the different database drivers and their compatibility wi - [PlanetScale Serverless](https://planetscale.com/docs/tutorials/planetscale-serverless-driver) uses HTTP to access the database. It works with Cloudflare Workers and Vercel Edge Functions. - [`node-postgres`](https://node-postgres.com/) (`pg`) uses Cloudflare's `connect()` (TCP) to access the database. It is only compatible with Cloudflare Workers, not with Vercel Edge Functions. - [`@libsql/client`](https://github.com/tursodatabase/libsql-client-ts) is used to access Turso databases. It works with Cloudflare Workers and Vercel Edge Functions. +- [Cloudflare D1](https://developers.cloudflare.com/d1/) is used to access D1 databases. It is only compatible with Cloudflare Workers, not with Vercel Edge Functions. There's [also work being done](https://github.com/sidorares/node-mysql2/pull/2289) on the `node-mysql2` driver which will enable access to traditional MySQL databases from Cloudflare Workers and Pages in the future as well. @@ -50,6 +51,7 @@ Depending on which deployment provider and database/driver you use, there may be - [PostgreSQL (traditional)](/orm/prisma-client/deployment/edge/deploy-to-cloudflare#postgresql-traditional) - [PlanetScale](/orm/prisma-client/deployment/edge/deploy-to-cloudflare#planetscale) - [Neon](/orm/prisma-client/deployment/edge/deploy-to-cloudflare#neon) + - [Cloudflare D1](/orm/prisma-client/deployment/edge/deploy-to-cloudflare#d1) - Vercel - [Vercel Postgres](/orm/prisma-client/deployment/edge/deploy-to-vercel#vercel-postgres) - [Neon](/orm/prisma-client/deployment/edge/deploy-to-vercel#neon) diff --git a/content/200-orm/200-prisma-client/500-deployment/301-edge/450-deploy-to-cloudflare.mdx b/content/200-orm/200-prisma-client/500-deployment/301-edge/450-deploy-to-cloudflare.mdx index a00ed6bf88..f5e03b5fcf 100644 --- a/content/200-orm/200-prisma-client/500-deployment/301-edge/450-deploy-to-cloudflare.mdx +++ b/content/200-orm/200-prisma-client/500-deployment/301-edge/450-deploy-to-cloudflare.mdx @@ -26,7 +26,8 @@ The edge-compatible drivers for Cloudflare Workers and Pages are: - [Neon Serverless](https://neon.tech/docs/serverless/serverless-driver) uses HTTP to access the database - [PlanetScale Serverless](https://planetscale.com/docs/tutorials/planetscale-serverless-driver) uses HTTP to access the database - [`node-postgres`](https://node-postgres.com/) (`pg`) uses Cloudflare's `connect()` (TCP) to access the database -- [`@libsql/client`](https://github.com/tursodatabase/libsql-client-ts) is used to access Turso databases +- [`@libsql/client`](https://github.com/tursodatabase/libsql-client-ts) is used to access Turso databases via HTTP +- [Cloudflare D1](/orm/prisma-client/deployment/edge/deploy-to-cloudflare#d1) is used to access D1 databases There's [also work being done](https://github.com/sidorares/node-mysql2/pull/2289) on the `node-mysql2` driver which will enable access to traditional MySQL databases from Cloudflare Workers and Pages in the future as well. @@ -134,6 +135,8 @@ npm install prisma --save-dev npx prisma init ``` +You'll further need a database instance of your database provider of choice available. Refer to the respective documentation of the provider for setting up that instance. + We'll use the default `User` model for the example below: ```prisma @@ -157,6 +160,8 @@ If you are running into a size issue and can't deploy your application because o #### 1. Configure Prisma schema & database connection +> **Note**: If you don't have a project to deploy, follow the instructions in the [Prerequisites](#prerequisites) to bootstrap a basic Cloudflare Worker with Prisma ORM in it. + First, ensure that the database connection is configured properly. In your Prisma schema, set the `url` of the `datasource` block to the `DATABASE_URL` environment variable. You also need to enable the `driverAdapters` feature flag: ```prisma file=schema.prisma @@ -304,6 +309,8 @@ If you are using a PlanetScale database, you need to: #### 1. Configure Prisma schema & database connection +> **Note**: If you don't have a project to deploy, follow the instructions in the [Prerequisites](#prerequisites) to bootstrap a basic Cloudflare Worker with Prisma ORM in it. + First, ensure that the database connection is configured properly. In your Prisma schema, set the `url` of the `datasource` block to the `DATABASE_URL` environment variable. You also need to enable the `driverAdapters` feature flag: ```prisma file=schema.prisma @@ -428,6 +435,8 @@ If you are using a Neon database, you need to: #### 1. Configure Prisma schema & database connection +> **Note**: If you don't have a project to deploy, follow the instructions in the [Prerequisites](#prerequisites) to bootstrap a basic Cloudflare Worker with Prisma ORM in it. + First, ensure that the database connection is configured properly. In your Prisma schema, set the `url` of the `datasource` block to the `DATABASE_URL` environment variable. You also need to enable the `driverAdapters` feature flag: ```prisma file=schema.prisma @@ -536,6 +545,199 @@ npx wrangler deploy The command will output the URL where you can access the deployed Worker. -### D1 +### Cloudflare D1 + +If you are using a D1 database, you need to: + +- use the `@prisma/adapter-d1` database adapter (via the `driverAdapters` Preview feature) +- set `sqlite` as the `datasource` provider in your Prisma schema +- manually generate SQL statements for schema changes using `prisma migrate diff` but execute them using [D1's migration system](https://developers.cloudflare.com/d1/reference/migrations/) + +You can find a [deployment-ready example on GitHub](https://github.com/prisma/prisma-examples/blob/latest/deployment-platforms/edge/cloudflare-workers/with-d1). + +#### 1. Configure Prisma schema + +> **Note**: If you don't have a project to deploy, follow the instructions in the [Prerequisites](#prerequisites) to bootstrap a basic Cloudflare Worker with Prisma ORM in it. + +In your Prisma schema, add the `driverAdapters` Preview feature to the `generator` block and 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: + +```prisma file=schema.prisma +generator client { + provider = "prisma-client-js" + previewFeatures = ["driverAdapters"] +} + +datasource db { + provider = "sqlite" + url = env("DATABASE_URL") +} + +model User { + id Int @id @default(autoincrement()) + email String @unique + name String? +} +``` + +Note that in this tutorial, you won't need the `.env` file since the connection between Prisma ORM and D1 will happen through a [binding](https://developers.cloudflare.com/workers/configuration/bindings/). + +#### 2. Install dependencies + +Next, install the required packages: + +```terminal +npm install @prisma/adapter-d1 +``` + +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. + +#### 3. Set the D1 database connection via a binding + +To connect your Workers with the D1 instance, add the following binding to your `wrangler.toml` (if you don't have a D1 instance yet, you can create one using the [Cloudflare Dashboard](https://dash.cloudflare.com/) or with the [`wrangler d1 create`](https://developers.cloudflare.com/workers/wrangler/commands/#create) command): + +```toml file=wrangler.toml +name = "prisma-cloudflare-worker-example" +main = "src/index.ts" +compatibility_date = "2024-03-20" +compatibility_flags = ["nodejs_compat"] + +[[d1_databases]] +binding = "DB" # i.e. available in your Worker on env.DB +database_name = "__YOUR_D1_DATABASE_NAME__" # to be replaced +database_id = "__YOUR_D1_DATABASE_ID__" # to be replaced +``` + +Note that `__YOUR_D1_DATABASE_NAME__` and `__YOUR_D1_DATABASE_ID__` in the snippet above are placeholders that should be replaced with the database name and ID of your own D1 instance. + +If you weren't able to grab this ID from the terminal output, you can also find it in the Cloudflare Dashboard or by running `npx wrangler d1 list` and `npx wrangler d1 info __YOUR_D1_DATABASE_NAME__` in your terminal. + +#### 4. Migrate your database schema (if applicable) + +If your Prisma schema only contains the `User` model but your D1 database is still empty, you need to make sure that there is a table in D1 that mirrors the structure of the `User` model. + +D1 comes with its own [migration system](https://developers.cloudflare.com/d1/reference/migrations/) that lets you manage migration files in your file system. While this is convenient for creating and applying migration files, it doesn't help you identifying the actual SQL statements that you need to put into these migration files. That's where Prisma Migrate comes into play, because you can generate SQL statements for schema changes using the [`prisma migrate diff`](/orm/reference/prisma-cli-reference#migrate-diff) command. + +First, create the `migrations` directory and initial migration file using the [`wrangler d1 migrations`](https://developers.cloudflare.com/workers/wrangler/commands/#migrations-create) command as follows: + +```terminal +npx wrangler d1 migrations create __YOUR_D1_DATABASE_NAME__ create_user_table +``` + +Replace `__YOUR_D1_DATABASE_NAME__` with the name of your database again and, when prompted, confirm that you want to create the `migrations` directory. After having run this command, there should be a new folder called `migrations` with a file called `0001_create_user_table.sql` inside of it. + +You can now generate the required SQL statement for creating a `User` table that can be mapped to the `User` model in your the Prisma schema as follows: + +```terminal +npx prisma migrate diff --from-empty --to-schema-datamodel ./prisma/schema.prisma --script > migrations/0001_create_user_table.sql +``` + +Note that the resulting SQL statement is stored in a file in the `migrations` directory called `0001_create_user_table.sql` which looks as follows: + +```sql file=migrations/0001_create_user_table.sql no-copy +-- CreateTable +CREATE TABLE "User" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "email" TEXT NOT NULL, + "name" TEXT +); + +-- CreateIndex +CREATE UNIQUE INDEX "User_email_key" ON "User"("email"); +``` + +You now need to use the [`wrangler d1 migrations apply`](https://developers.cloudflare.com/workers/wrangler/commands/#migrations-apply) command to send this SQL statement to D1. Note that this command accepts two options: + +- `--local`: Executes the statement against a _local_ version of D1. This local version of D1 is a SQLite database file that'll be located in your project. This approach is useful, when you want to develop and test your Worker on your local machine. Learn more in the [Cloudflare docs](https://developers.cloudflare.com/d1/configuration/local-development/). +- `--remote`: Executes the statement against your _remote_ version of D1. This version is used by your _deployed_ Cloudflare Workers. Learn more in the [Cloudflare docs](https://developers.cloudflare.com/d1/configuration/remote-development/). + +In this tutorial, you'll do both: test the Worker locally _and_ deploy it afterwards. So, you need to run both commands. Open your terminal and paste the following commands: + +```terminal +# For the local database +npx wrangler d1 migrations apply __YOUR_D1_DATABASE_NAME__ --local + +# For the remote database +npx wrangler d1 migrations apply __YOUR_D1_DATABASE_NAME__ --remote +``` + +As before, you need to replace `__YOUR_D1_DATABASE_NAME__` with the name of your D1 database. + +Let's also create some dummy data that we can query once the Worker is running. This time, you'll run the SQL statement without storing it in a file: + +```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 -[Coming soon](https://github.com/prisma/prisma/issues/13310). +# 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 +``` + +#### 5. Use Prisma Client in your Worker to send a query to the database + +Before adding a Prisma Client query to your Worker, you need to generate Prisma Client with the following command: + +``` +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. +3. Send a query using Prisma Client and return the result. + +Open `src/index.ts` and replace the entire content with the following: + +```typescript file=src/index.ts +import { PrismaClient } from '@prisma/client' +import { PrismaD1 } from '@prisma/adapter-d1' + +export interface Env { + DB: D1Database +} + +export default { + async fetch( + request: Request, + env: Env, + ctx: ExecutionContext + ): Promise { + const adapter = new PrismaD1(env.DB) + const prisma = new PrismaClient({ adapter }) + + const users = await prisma.user.findMany() + const result = JSON.stringify(users) + return new Response(result) + }, +} +``` + +#### 6. Run the Worker locally + +With the database query in place and Prisma Client generated, you can go ahead and run the Worker locally: + +``` +npm run dev +``` + +Now you can open your browser at [`http://localhost:8787`](http://localhost:8787/) to see the result of the database query: + +```js no-copy +;[{ id: 1, email: 'jane@prisma.io', name: 'Jane Doe (Local)' }] +``` + +#### 7. Set the `DATABASE_URL` environment variable and deploy the Worker + +To deploy the Worker, run the the following command: + +``` +npm run deploy +``` + +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: + +```js no-copy +;[{ id: 1, email: 'jane@prisma.io', name: 'Jane Doe (Remote)' }] +``` diff --git a/content/200-orm/200-prisma-client/500-deployment/301-edge/485-deploy-to-vercel.mdx b/content/200-orm/200-prisma-client/500-deployment/301-edge/485-deploy-to-vercel.mdx index e2f234b39a..0453976349 100644 --- a/content/200-orm/200-prisma-client/500-deployment/301-edge/485-deploy-to-vercel.mdx +++ b/content/200-orm/200-prisma-client/500-deployment/301-edge/485-deploy-to-vercel.mdx @@ -116,6 +116,8 @@ If you are using Vercel Postgres, you need to: #### 1. Configure Prisma schema & database connection +> **Note**: If you don't have a project to deploy, follow the instructions in the [Prerequisites](#prerequisites) to bootstrap a basic Next.js app with Prisma ORM in it. + First, ensure that the database connection is configured properly. In your Prisma schema, set the `url` of the `datasource` block to the `POSTGRES_PRISMA_URL` and the `directUrl` to the `POSTGRES_URL_NON_POOLING` environment variable. You also need to enable the `driverAdapters` feature flag: ```prisma file=schema.prisma @@ -238,6 +240,8 @@ If you are using a PlanetScale database, you need to: #### 1. Configure Prisma schema & database connection +> **Note**: If you don't have a project to deploy, follow the instructions in the [Prerequisites](#prerequisites) to bootstrap a basic Next.js app with Prisma ORM in it. + First, ensure that the database connection is configured properly. In your Prisma schema, set the `url` of the `datasource` block to the `DATABASE_URL` environment variable. You also need to enable the `driverAdapters` feature flag: ```prisma file=schema.prisma @@ -357,6 +361,8 @@ If you are using a Neon database, you need to: #### 1. Configure Prisma schema & database connection +> **Note**: If you don't have a project to deploy, follow the instructions in the [Prerequisites](#prerequisites) to bootstrap a basic Next.js app with Prisma ORM in it. + First, ensure that the database connection is configured properly. In your Prisma schema, set the `url` of the `datasource` block to the `DATABASE_URL` environment variable. You also need to enable the `driverAdapters` feature flag: ```prisma file=schema.prisma diff --git a/content/200-orm/500-reference/375-supported-databases.mdx b/content/200-orm/500-reference/375-supported-databases.mdx index 771acdaee4..e1caa4f4d7 100644 --- a/content/200-orm/500-reference/375-supported-databases.mdx +++ b/content/200-orm/500-reference/375-supported-databases.mdx @@ -50,5 +50,6 @@ Note that a fixed version of SQLite is shipped with every Prisma ORM release. | MongoDB Atlas | \* | | Neon Serverless Postgres | \* | | PlanetScale | \* | +| Cloudflare D1 (Preview) | \* | ¹ This does not include support for [Data API for Aurora Serverless](https://github.com/prisma/prisma/issues/1964). diff --git a/content/300-accelerate/650-troubleshoot.mdx b/content/300-accelerate/650-troubleshoot.mdx index c36ca512a8..482fbf1d27 100644 --- a/content/300-accelerate/650-troubleshoot.mdx +++ b/content/300-accelerate/650-troubleshoot.mdx @@ -14,7 +14,7 @@ When working with Prisma Accelerate, you may encounter errors often highlighted ## [P6009](/orm/reference/error-reference#p6009-responsesizelimitexceeded) (ResponseSizeLimitExceeded) -This error is triggered when the response size from a database query exceeds the 5MB limit. We've implemented this restriction to safeguard your application performance, as retrieving data over 5MB can significantly slow down your application due to multiple network layers. Typically, transmitting more than 5MB of data is common when conducting ETL (Extract, Transform, Load) operations. However, for other scenarios such as transactional queries, real-time data fetching for user interfaces, bulk data updates, or aggregating large datasets for analytics outside of ETL contexts, it should generally be avoided. These use cases, while essential, can often be optimised to work within the 5MB limit, ensuring smoother performance and a better user experience. +This error is triggered when the response size from a database query exceeds the 5MB limit. We've implemented this restriction to safeguard your application performance, as retrieving data over 5MB can significantly slow down your application due to multiple network layers. Typically, transmitting more than 5MB of data is common when conducting ETL (Extract, Transform, Load) operations. However, for other scenarios such as transactional queries, real-time data fetching for user interfaces, bulk data updates, or aggregating large datasets for analytics outside of ETL contexts, it should generally be avoided. These use cases, while essential, can often be optimized to work within the 5MB limit, ensuring smoother performance and a better user experience. ### Possible causes for [P6009](/orm/reference/error-reference#p6009-responsesizelimitexceeded)