diff --git a/docs/100-getting-started/01-quickstart.mdx b/docs/100-getting-started/01-quickstart.mdx new file mode 100644 index 0000000000..440faaa0b3 --- /dev/null +++ b/docs/100-getting-started/01-quickstart.mdx @@ -0,0 +1,418 @@ +--- +title: 'Quickstart' +duration: '5 min' +metaTitle: 'Quickstart with TypeScript & SQLite' +metaDescription: 'Get started with Prisma in 5 minutes. You will learn how to send queries to a SQLite database in a plain TypeScript script using Prisma Client.' +search: true +--- + + + +In this Quickstart guide, you'll learn how to get started with Prisma from scratch using a plain **TypeScript** project and a local **SQLite** database file. It covers **data modeling**, **migrations** and **querying** a database. + +If you want to use Prisma with your own PostgreSQL, MySQL, MongoDB or any other supported database, go here instead: + +- [Start with Prisma from scratch](/getting-started/setup-prisma/start-from-scratch/relational-databases-typescript-postgresql) +- [Add Prisma to an existing project](/getting-started/setup-prisma/add-to-existing-project/relational-databases-typescript-postgresql) + + + +## Prerequisites + +You need Node.js v16.13.0 or higher for this guide (learn more about [system requirements](/orm/reference/system-requirements)). + +## 1. Create TypeScript project and set up Prisma + +As a first step, create a project directory and navigate into it: + +```terminal +mkdir hello-prisma +cd hello-prisma +``` + +Next, initialize a TypeScript project using npm: + +```terminal +npm init -y +npm install typescript ts-node @types/node --save-dev +``` + +This creates a `package.json` with an initial setup for your TypeScript app. + + + +See [installation instructions](/orm/tools/prisma-cli#installation) to learn how to install Prisma using a different package manager. + + + +Now, initialize TypeScript: + +```terminal +npx tsc --init +``` + +Then, install the Prisma CLI as a development dependency in the project: + +```terminal +npm install prisma --save-dev +``` + +Finally, set up Prisma with the `init` command of the Prisma CLI: + +```terminal +npx prisma init --datasource-provider sqlite +``` + +This creates a new `prisma` directory with your Prisma schema file and configures SQLite as your database. You're now ready to model your data and create your database with some tables. + +## 2. Model your data in the Prisma schema + +The Prisma schema provides an intuitive way to model data. Add the following models to your `schema.prisma` file: + +```prisma file=prisma/schema.prisma +model User { + id Int @id @default(autoincrement()) + email String @unique + name String? + posts Post[] +} + +model Post { + id Int @id @default(autoincrement()) + title String + content String? + published Boolean @default(false) + author User @relation(fields: [authorId], references: [id]) + authorId Int +} +``` + +Models in the Prisma schema have two main purposes: + +- Represent the tables in the underlying database +- Serve as foundation for the generated Prisma Client API + +In the next section, you will map these models to database tables using Prisma Migrate. + +## 3. Run a migration to create your database tables with Prisma Migrate + +At this point, you have a Prisma schema but no database yet. Run the following command in your terminal to create the SQLite database and the `User` and `Post` tables represented by your models: + +```terminal +npx prisma migrate dev --name init +``` + +This command did three things: + +1. It created a new SQL migration file for this migration in the `prisma/migrations` directory. +2. It executed the SQL migration file against the database. +3. It ran `prisma generate` under the hood (which installed the `@prisma/client` package and generated a tailored Prisma Client API based on your models). + +Because the SQLite database file didn't exist before, the command also created it inside the `prisma` directory with the name `dev.db` as defined via the environment variable in the `.env` file. + +Congratulations, you now have your database and tables ready. Let's go and learn how you can send some queries to read and write data! + +## 4. Explore how to send queries to your database with Prisma Client + +To send queries to the database, you will need a TypeScript file to execute your Prisma Client queries. Create a new file called `script.ts` for this purpose: + +```terminal +touch script.ts +``` + +Then, paste the following boilerplate into it: + +```ts file=script.ts +import { PrismaClient } from '@prisma/client' + +const prisma = new PrismaClient() + +async function main() { + // ... you will write your Prisma Client queries here +} + +main() + .then(async () => { + await prisma.$disconnect() + }) + .catch(async (e) => { + console.error(e) + await prisma.$disconnect() + process.exit(1) + }) +``` + +This code contains a `main` function that's invoked at the end of the script. It also instantiates `PrismaClient` which represents the query interface to your database. + +### 4.1. Create a new `User` record + +Let's start with a small query to create a new `User` record in the database and log the resulting object to the console. Add the following code to your `script.ts` file: + +```ts file=script.ts highlight=6-12;add +import { PrismaClient } from '@prisma/client' + +const prisma = new PrismaClient() + +async function main() { + const user = await prisma.user.create({ + data: { + name: 'Alice', + email: 'alice@prisma.io', + }, + }) + console.log(user) +} + +main() + .then(async () => { + await prisma.$disconnect() + }) + .catch(async (e) => { + console.error(e) + await prisma.$disconnect() + process.exit(1) + }) +``` + +Instead of copying the code, you can type it out in your editor to experience the autocompletion Prisma Client provides. You can also actively invoke the autocompletion by pressing the CTRL+SPACE keys on your keyboard. + +Next, execute the script with the following command: + + + + + +```terminal +npx ts-node script.ts +``` + + + + + +```code no-copy +{ id: 1, email: 'alice@prisma.io', name: 'Alice' } +``` + + + + + +Great job, you just created your first database record with Prisma Client! πŸŽ‰ + +In the next section, you'll learn how to read data from the database. + +### 4.2. Retrieve all `User` records + +Prisma Client offers various queries to read data from your database. In this section, you'll use the `findMany` query that returns _all_ the records in the database for a given model. + +Delete the previous Prisma Client query and add the new `findMany` query instead: + +```ts file=script.ts highlight=6-7;add +import { PrismaClient } from '@prisma/client' + +const prisma = new PrismaClient() + +async function main() { + const users = await prisma.user.findMany() + console.log(users) +} + +main() + .then(async () => { + await prisma.$disconnect() + }) + .catch(async (e) => { + console.error(e) + await prisma.$disconnect() + process.exit(1) + }) +``` + +Execute the script again: + + + + + +```terminal +npx ts-node script.ts +``` + + + + + +```code no-copy +[{ id: 1, email: 'alice@prisma.io', name: 'Alice' }] +``` + + + + + +Notice how the single `User` object is now enclosed with square brackets in the console. That's because the `findMany` returned an array with a single object inside. + +### 4.3. Explore relation queries with Prisma + +One of the main features of Prisma Client is the ease of working with [relations](/orm/prisma-schema/data-model/relations). In this section, you'll learn how to create a `User` and a `Post` record in a nested write query. Afterwards, you'll see how you can retrieve the relation from the database using the `include` option. + +First, adjust your script to include the nested query: + +```ts file=script.ts highlight=6-17;add +import { PrismaClient } from '@prisma/client' + +const prisma = new PrismaClient() + +async function main() { + const user = await prisma.user.create({ + data: { + name: 'Bob', + email: 'bob@prisma.io', + posts: { + create: { + title: 'Hello World', + }, + }, + }, + }) + console.log(user) +} + +main() + .then(async () => { + await prisma.$disconnect() + }) + .catch(async (e) => { + console.error(e) + await prisma.$disconnect() + process.exit(1) + }) +``` + +Run the query by executing the script again: + + + + + +```terminal +npx ts-node script.ts +``` + + + + + +```code no-copy +{ id: 2, email: 'bob@prisma.io', name: 'Bob' } +``` + + + + + +By default, Prisma only returns _scalar_ fields in the result objects of a query. That's why, even though you also created a new `Post` record for the new `User` record, the console only printed an object with three scalar fields: `id`, `email` and `name`. + +In order to also retrieve the `Post` records that belong to a `User`, you can use the `include` option via the `posts` relation field: + +```ts file=script.ts highlight=6-11;add +import { PrismaClient } from '@prisma/client' + +const prisma = new PrismaClient() + +async function main() { + const usersWithPosts = await prisma.user.findMany({ + include: { + posts: true, + }, + }) + console.dir(usersWithPosts, { depth: null }) +} + +main() + .then(async () => { + await prisma.$disconnect() + }) + .catch(async (e) => { + console.error(e) + await prisma.$disconnect() + process.exit(1) + }) +``` + +Run the script again to see the results of the nested read query: + + + + + +```terminal +npx ts-node script.ts +``` + + + + + +```code no-copy +[ + { id: 1, email: 'alice@prisma.io', name: 'Alice', posts: [] }, + { + id: 2, + email: 'bob@prisma.io', + name: 'Bob', + posts: [ + { + id: 1, + title: 'Hello World', + content: null, + published: false, + authorId: 2 + } + ] + } +] +``` + + + + + +This time, you're seeing two `User` objects being printed. Both of them have a `posts` field (which is empty for `"Alice"` and populated with a single `Post` object for `"Bob"`) that represents the `Post` records associated with them. + +Notice that the objects in the `usersWithPosts` array are fully typed as well. This means you will get autocompletion and the TypeScript compiler will prevent you from accidentally typing them. + +## 5. Next steps + +In this Quickstart guide, you have learned how to get started with Prisma in a plain TypeScript project. Feel free to explore the Prisma Client API a bit more on your own, e.g. by including filtering, sorting, and pagination options in the `findMany` query or exploring more operations like `update` and `delete` queries. + +### Explore the data in Prisma Studio + +Prisma comes with a built-in GUI to view and edit the data in your database. You can open it using the following command: + +```terminal +npx prisma studio +``` + +### Set up Prisma with your own database + +If you want to move forward with Prisma using your own PostgreSQL, MySQL, MongoDB or any other supported database, follow the Set Up Prisma guides: + +- [Start with Prisma from scratch](/getting-started/setup-prisma/start-from-scratch/relational-databases-typescript-postgresql) +- [Add Prisma to an existing project](/getting-started/setup-prisma/add-to-existing-project) + +### Explore ready-to-run Prisma examples + +Check out the [`prisma-examples`](https://github.com/prisma/prisma-examples/) repository on GitHub to see how Prisma can be used with your favorite library. The repo contains examples with Express, NestJS, GraphQL as well as fullstack examples with Next.js and Vue.js, and a lot more. + +### Build an app with Prisma + +The Prisma blog features comprehensive tutorials about Prisma, check out our latest ones: + +- [Build a fullstack app with Remix](https://www.prisma.io/blog/fullstack-remix-prisma-mongodb-1-7D0BfTXBmB6r) (5 parts, including videos) +- [Build a REST API with NestJS](https://www.prisma.io/blog/nestjs-prisma-rest-api-7D056s1BmOL0) + +### Join the Prisma community πŸ’š + +Prisma has a huge [community](https://www.prisma.io/community) of developers. Join us on [Slack](https://slack.prisma.io) or [Discord](https://discord.gg/KQyTW2H5ca) and ask questions via [GitHub Discussions](https://github.com/prisma/prisma/discussions). diff --git a/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/110-relational-databases/100-connect-your-database.mdx b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/110-relational-databases/100-connect-your-database.mdx new file mode 100644 index 0000000000..f530bd284a --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/110-relational-databases/100-connect-your-database.mdx @@ -0,0 +1,550 @@ +--- +title: 'Connect your database' +metaTitle: 'Connect your database' +metaDescription: 'Connect your database to your project' +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['postgresql', 'mysql', 'sqlserver', 'planetscale', 'cockroachdb'] +toc: false +--- + +## Connect your database + +To connect your database, you need to set the `url` field of the `datasource` block in your Prisma schema to your database [connection URL](/orm/reference/connection-urls): + + + +```prisma file=prisma/schema.prisma +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} +``` + +In this case, the `url` is [set via an environment variable](/orm/more/development-environment/environment-variables) which is defined in `.env`: + +```bash file=.env +DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public" +``` + + + +We recommend adding `.env` to your `.gitignore` file to prevent committing your environment variables. + + + +You now need to adjust the connection URL to point to your own database. + +The [format of the connection URL](/orm/reference/connection-urls) for your database depends on the database you use. For PostgreSQL, it looks as follows (the parts spelled all-uppercased are _placeholders_ for your specific connection details): + +```no-lines +postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=SCHEMA +``` + +Here's a short explanation of each component: + +- `USER`: The name of your database user +- `PASSWORD`: The password for your database user +- `HOST`: The name of your host name (for the local environment, it is `localhost`) +- `PORT`: The port where your database server is running (typically `5432` for PostgreSQL) +- `DATABASE`: The name of the [database](https://www.postgresql.org/docs/12/manage-ag-overview.html) +- `SCHEMA`: The name of the [schema](https://www.postgresql.org/docs/12/ddl-schemas.html) inside the database + +If you're unsure what to provide for the `schema` parameter for a PostgreSQL connection URL, you can probably omit it. In that case, the default schema name `public` will be used. + +As an example, for a PostgreSQL database hosted on Heroku, the [connection URL](/orm/reference/connection-urls) might look similar to this: + +```bash file=.env +DATABASE_URL="postgresql://opnmyfngbknppm:XXX@ec2-46-137-91-216.eu-west-1.compute.amazonaws.com:5432/d50rgmkqi2ipus?schema=hello-prisma" +``` + +When running PostgreSQL locally on macOS, your user and password as well as the database name _typically_ correspond to the current _user_ of your OS, e.g. assuming the user is called `janedoe`: + +```bash file=.env +DATABASE_URL="postgresql://janedoe:janedoe@localhost:5432/janedoe?schema=hello-prisma" +``` + + + + + +```prisma file=prisma/schema.prisma +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} +``` + +Note that the default schema created by `prisma init` uses PostgreSQL, so you first need to switch the `provider` to `mysql`: + +```prisma file=prisma/schema.prisma highlight=2;edit +datasource db { + provider = "mysql" + url = env("DATABASE_URL") +} +``` + +In this case, the `url` is [set via an environment variable](/orm/prisma-schema/overview#accessing-environment-variables-from-the-schema) which is defined in `.env`: + +```bash file=.env +DATABASE_URL="mysql://johndoe:randompassword@localhost:3306/mydb" +``` + + + +We recommend adding `.env` to your `.gitignore` file to prevent committing your environment variables. + + + +You now need to adjust the connection URL to point to your own database. + +The [format of the connection URL](/orm/reference/connection-urls) for your database typically depends on the database you use. For MySQL, it looks as follows (the parts spelled all-uppercased are _placeholders_ for your specific connection details): + +```no-lines +mysql://USER:PASSWORD@HOST:PORT/DATABASE +``` + +Here's a short explanation of each component: + +- `USER`: The name of your database user +- `PASSWORD`: The password for your database user +- `PORT`: The port where your database server is running (typically `3306` for MySQL) +- `DATABASE`: The name of the [database](https://dev.mysql.com/doc/refman/8.0/en/creating-database.html) + +As an example, for a MySQL database hosted on AWS RDS, the [connection URL](/orm/reference/connection-urls) might look similar to this: + +```bash file=.env +DATABASE_URL="mysql://johndoe:XXX@mysql–instance1.123456789012.us-east-1.rds.amazonaws.com:3306/mydb" +``` + +When running MySQL locally, your connection URL typically looks similar to this: + +```bash file=.env +DATABASE_URL="mysql://root:randompassword@localhost:3306/mydb" +``` + + + + + +```prisma file=prisma/schema.prisma +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} +``` + +Note that the default schema created by `prisma init` uses PostgreSQL as the `provider`. For PlanetScale, you need to edit the `datasource` block to use the `mysql` provider instead: + +```prisma file=prisma/schema.prisma highlight=2;edit +datasource db { + provider = "mysql" + url = env("DATABASE_URL") +} +``` + +You will also need to [set the relation mode type to `prisma`](/orm/prisma-schema/data-model/relations/relation-mode#emulate-relations-in-prisma-with-the-prisma-relation-mode) in the `datasource` block: + +```prisma file=schema.prisma highlight=4;add +datasource db { + provider = "mysql" + url = env("DATABASE_URL") + relationMode = "prisma" +} +``` + +The `url` is [set via an environment variable](/orm/prisma-schema/overview#accessing-environment-variables-from-the-schema) which is defined in `.env`: + +```bash file=.env +DATABASE_URL="mysql://janedoe:mypassword@server.us-east-2.psdb.cloud/mydb?sslaccept=strict" +``` + +You now need to adjust the connection URL to point to your own database. + +The [format of the connection URL](/orm/reference/connection-urls) for your database typically depends on the database you use. PlanetScale uses the MySQL connection URL format, which has the following structure (the parts spelled all-uppercased are _placeholders_ for your specific connection details): + +```no-lines +mysql://USER:PASSWORD@HOST:PORT/DATABASE +``` + +Here's a short explanation of each component: + +- `USER`: The name of your database user +- `PASSWORD`: The password for your database user +- `PORT`: The port where your database server is running (typically `3306` for MySQL) +- `DATABASE`: The name of the [database](https://dev.mysql.com/doc/refman/8.0/en/creating-database.html) + +For a database hosted with PlanetScale, the [connection URL](/orm/reference/connection-urls) looks similar to this: + +```bash file=.env +DATABASE_URL="mysql://myusername:mypassword@server.us-east-2.psdb.cloud/mydb?sslaccept=strict" +``` + +The connection URL for a given database branch can be found from your PlanetScale account by going to the overview page for the branch and selecting the 'Connect' dropdown. In the 'Passwords' section, generate a new password and select 'Prisma' to get the Prisma format for the connection URL. + +
+Alternative method: connecting using the PlanetScale CLI + +Alternatively, you can connect to your PlanetScale database server using the [PlanetScale CLI](https://docs.planetscale.com/reference/planetscale-environment-setup), and use a local connection URL. In this case the connection URL will look like this: + +```bash file=.env +DATABASE_URL="mysql://root@localhost:PORT/mydb" +``` + + + +We recommend adding `.env` to your `.gitignore` file to prevent committing your environment variables. + + + +To connect to your branch, use the following command: + +```terminal +pscale connect prisma-test branchname --port PORT +``` + +The `--port` flag can be omitted if you are using the default port `3306`. + +
+ +
+ + + +```prisma file=prisma/schema.prisma +datasource db { + provider = "sqlserver" + url = env("DATABASE_URL") +} +``` + +In this case, the `url` is [set via an environment variable](/orm/prisma-schema/overview#accessing-environment-variables-from-the-schema) which is defined in `.env`: + +The following example connection URL [uses SQL authentication](/orm/overview/databases/sql-server), but there are [other ways to format your connection URL](/orm/overview/databases/sql-server) + +```bash file=.env + DATABASE_URL="sqlserver://localhost:1433;database=mydb;user=sa;password=r@ndomP@$$w0rd;trustServerCertificate=true" +``` + + + +We recommend adding `.env` to your `.gitignore` file to prevent committing your environment variables. + + + +Adjust the connection URL to match your setup - see [Microsoft SQL Server connection URL](/orm/overview/databases/sql-server) for more information. + +> Make sure TCP/IP connections are enabled via [SQL Server Configuration Manager](https://docs.microsoft.com/en-us/sql/relational-databases/sql-server-configuration-manager) to avoid `No connection could be made because the target machine actively refused it. (os error 10061)` + + + + + +```prisma file=prisma/schema.prisma +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} +``` + +Note that the default schema created by `prisma init` uses PostgreSQL as the `provider`. For CockroachDB, you need to edit the `datasource` block to use the `cockroachdb` provider instead: + +```prisma file=prisma/schema.prisma highlight=2;edit +datasource db { + provider = "cockroachdb" + url = env("DATABASE_URL") +} +``` + +The `url` is [set via an environment variable](/orm/more/development-environment/environment-variables) which is defined in `.env`. You now need to adjust the connection URL to point to your own database. + +The [format of the connection URL](/orm/reference/connection-urls) for your database depends on the database you use. CockroachDB uses the PostgreSQL connection URL format, which has the following structure (the parts spelled all-uppercased are _placeholders_ for your specific connection details): + +```no-lines +postgresql://USER:PASSWORD@HOST:PORT/DATABASE?PARAMETERS +``` + +Here's a short explanation of each component: + +- `USER`: The name of your database user +- `PASSWORD`: The password for your database user +- `PORT`: The port where your database server is running. The default for CockroachDB is `26257`. +- `DATABASE`: The name of the database +- `PARAMETERS`: Any additional connection parameters. See the CockroachDB documentation [here](https://www.cockroachlabs.com/docs/stable/connection-parameters.html#additional-connection-parameters). + +For a [CockroachDB Serverless](https://www.cockroachlabs.com/docs/cockroachcloud/quickstart.html) or [Cockroach Dedicated](https://www.cockroachlabs.com/docs/cockroachcloud/quickstart-trial-cluster) database hosted on [CockroachDB Cloud](https://www.cockroachlabs.com/get-started-cockroachdb/), the [connection URL](/orm/reference/connection-urls) looks similar to this: + +```bash file=.env +DATABASE_URL="postgresql://:@..cockroachlabs.cloud:26257/defaultdb?sslmode=verify-full&sslrootcert=$HOME/.postgresql/root.crt&options=--" +``` + +To find your connection string on CockroachDB Cloud, click the 'Connect' button on the overview page for your database cluster, and select the 'Connection string' tab. + +For a [CockroachDB database hosted locally](https://www.cockroachlabs.com/docs/stable/secure-a-cluster.html), the [connection URL](/orm/reference/connection-urls) looks similar to this: + +```bash file=.env +DATABASE_URL="postgresql://root@localhost:26257?sslmode=disable" +``` + +Your connection string is displayed as part of the welcome text when starting CockroachDB from the command line. + + + + + + + + + Installation + + + + Using Prisma Migrate + + + + + + + + + + + + Installation + + + + Using Prisma Migrate + + + + + + + + + + + + Installation + + + + Creating the database schema + + + + + + + + + + + + Installation + + + + Using Prisma Migrate + + + + + + + + + + + + Installation + + + + Using Prisma Migrate + + + + + + + + + + + + Installation + + + + Using Prisma Migrate + + + + + + + + + + + + Installation + + + + Using Prisma Migrate + + + + + + + + + + + + Installation + + + + Creating the database schema + + + + + + + + + + + + Installation + + + + Using Prisma Migrate + + + + + + + + + + + + Installation + + + + Using Prisma Migrate + + + + + diff --git a/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/110-relational-databases/150-using-prisma-migrate.mdx b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/110-relational-databases/150-using-prisma-migrate.mdx new file mode 100644 index 0000000000..08aaa968d3 --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/110-relational-databases/150-using-prisma-migrate.mdx @@ -0,0 +1,841 @@ +--- +title: 'Using Prisma Migrate' +metaTitle: 'Using Prisma Migrate' +metaDescription: 'Create database tables with Prisma Migrate' +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['postgresql', 'mysql', 'sqlserver', 'planetscale', 'cockroachdb'] +toc: false +--- + +## Creating the database schema + + + +In this guide, you'll use [Prisma Migrate](/orm/prisma-migrate) to create the tables in your database. Add the following Prisma data model to your [Prisma schema](/orm/prisma-schema) in `prisma/schema.prisma`: + +```prisma file=prisma/schema.prisma copy +model Post { + id Int @id @default(autoincrement()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + title String @db.VarChar(255) + content String? + published Boolean @default(false) + author User @relation(fields: [authorId], references: [id]) + authorId Int +} + +model Profile { + id Int @id @default(autoincrement()) + bio String? + user User @relation(fields: [userId], references: [id]) + userId Int @unique +} + +model User { + id Int @id @default(autoincrement()) + email String @unique + name String? + posts Post[] + profile Profile? +} +``` + +To map your data model to the database schema, you need to use the `prisma migrate` CLI commands: + +```terminal +npx prisma migrate dev --name init +``` + +This command does two things: + +1. It creates a new SQL migration file for this migration +1. It runs the SQL migration file against the database + +> **Note**: `generate` is called under the hood by default, after running `prisma migrate dev`. If the `prisma-client-js` generator is defined in your schema, this will check if `@prisma/client` is installed and install it if it's missing. + +Great, you now created three tables in your database with Prisma Migrate πŸš€ + + + + + +In this guide, you'll use [Prisma Migrate](/orm/prisma-migrate) to create the tables in your database. Add the following Prisma data model to your Prisma schema in `prisma/schema.prisma`: + +```prisma file=prisma/schema.prisma copy +model Post { + id Int @id @default(autoincrement()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + title String @db.VarChar(255) + content String? + published Boolean @default(false) + author User @relation(fields: [authorId], references: [id]) + authorId Int +} + +model Profile { + id Int @id @default(autoincrement()) + bio String? + user User @relation(fields: [userId], references: [id]) + userId Int @unique +} + +model User { + id Int @id @default(autoincrement()) + email String @unique + name String? + posts Post[] + profile Profile? +} +``` + +To map your data model to the database schema, you need to use the `prisma migrate` CLI commands: + +```terminal +npx prisma migrate dev --name init +``` + +This command does two things: + +1. It creates a new SQL migration file for this migration +1. It runs the SQL migration file against the database + +> **Note**: `generate` is called under the hood by default, after running `prisma migrate dev`. If the `prisma-client-js` generator is defined in your schema, this will check if `@prisma/client` is installed and install it if it's missing. + +Great, you now created three tables in your database with Prisma Migrate πŸš€ + + + + + +In this guide, you'll use Prisma's [`db push` command](/orm/prisma-migrate/workflows/prototyping-your-schema) to create the tables in your database. Add the following Prisma data model to your Prisma schema in `prisma/schema.prisma`: + +```prisma file=prisma/schema.prisma copy +model Post { + id Int @id @default(autoincrement()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + title String @db.VarChar(255) + content String? + published Boolean @default(false) + author User @relation(fields: [authorId], references: [id]) + authorId Int + + @@index(authorId) +} + +model Profile { + id Int @id @default(autoincrement()) + bio String? + user User @relation(fields: [userId], references: [id]) + userId Int @unique + + @@index(userId) +} + +model User { + id Int @id @default(autoincrement()) + email String @unique + name String? + posts Post[] + profile Profile? +} +``` + +You are now ready to push your new schema to your database. Connect to your `main` branch using the instructions in [Connect your database](/getting-started/setup-prisma/start-from-scratch/relational-databases/connect-your-database-typescript-planetscale). + +Now use the `db push` CLI command to push to the `main` branch: + +```terminal +npx prisma db push +``` + +Great, you now created three tables in your database with Prisma's `db push` command πŸš€ + + + + + +In this guide, you'll use [Prisma Migrate](/orm/prisma-migrate) to create the tables in your database. Add the following Prisma data model to your Prisma schema in `prisma/schema.prisma`: + +```prisma file=prisma/schema.prisma copy +model Post { + id Int @id @default(autoincrement()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + title String @db.VarChar(255) + content String? + published Boolean @default(false) + author User @relation(fields: [authorId], references: [id]) + authorId Int +} + +model Profile { + id Int @id @default(autoincrement()) + bio String? + user User @relation(fields: [userId], references: [id]) + userId Int @unique +} + +model User { + id Int @id @default(autoincrement()) + email String @unique + name String? + posts Post[] + profile Profile? +} +``` + +To map your data model to the database schema, you need to use the `prisma migrate` CLI commands: + +```terminal +npx prisma migrate dev --name init +``` + +This command does two things: + +1. It creates a new SQL migration file for this migration +1. It runs the SQL migration file against the database + +> **Note**: `generate` is called under the hood by default, after running `prisma migrate dev`. If the `prisma-client-js` generator is defined in your schema, this will check if `@prisma/client` is installed and install it if it's missing. + +Great, you now created three tables in your database with Prisma Migrate πŸš€ + + + + + + + + + +```sql +CREATE TABLE "Post" ( + "id" SERIAL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + "title" VARCHAR(255) NOT NULL, + "content" TEXT, + "published" BOOLEAN NOT NULL DEFAULT false, + "authorId" INTEGER NOT NULL, + PRIMARY KEY ("id") +); + +CREATE TABLE "Profile" ( + "id" SERIAL, + "bio" TEXT, + "userId" INTEGER NOT NULL, + PRIMARY KEY ("id") +); + +CREATE TABLE "User" ( + "id" SERIAL, + "email" TEXT NOT NULL, + "name" TEXT, + PRIMARY KEY ("id") +); + +CREATE UNIQUE INDEX "Profile.userId_unique" ON "Profile"("userId"); +CREATE UNIQUE INDEX "User.email_unique" ON "User"("email"); +ALTER TABLE "Post" ADD FOREIGN KEY("authorId")REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE "Profile" ADD FOREIGN KEY("userId")REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; +``` + + + + + +**User** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :-------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `INTEGER` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `name` | `TEXT` | No | No | No | - | +| `email` | `TEXT` | No | No | **βœ”οΈ** | - | + +**Post** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :------------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `INTEGER` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `createdAt` | `TIMESTAMP` | No | No | **βœ”οΈ** | `now()` | +| `updatedAt` | `TIMESTAMP` | No | No | **βœ”οΈ** | | +| `title` | `VARCHAR(255)` | No | No | **βœ”οΈ** | - | +| `content` | `TEXT` | No | No | No | - | +| `published` | `BOOLEAN` | No | No | **βœ”οΈ** | `false` | +| `authorId` | `INTEGER` | No | **βœ”οΈ** | **βœ”οΈ** | - | + +**Profile** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :-------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `INTEGER` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `bio` | `TEXT` | No | No | No | - | +| `userId` | `INTEGER` | No | **βœ”οΈ** | **βœ”οΈ** | - | + + + + + + + + + + + + + +```sql +CREATE TABLE "Post" ( + "id" SERIAL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + "title" TEXT NOT NULL, + "content" TEXT, + "published" BOOLEAN NOT NULL DEFAULT false, + "authorId" INTEGER NOT NULL, + PRIMARY KEY ("id") +); + +CREATE TABLE "Profile" ( + "id" SERIAL, + "bio" TEXT, + "userId" INTEGER NOT NULL, + PRIMARY KEY ("id") +); + +CREATE TABLE "User" ( + "id" SERIAL, + "email" TEXT NOT NULL, + "name" TEXT, + PRIMARY KEY ("id") +); + +CREATE UNIQUE INDEX "Profile.userId_unique" ON "Profile"("userId"); +CREATE UNIQUE INDEX "User.email_unique" ON "User"("email"); +ALTER TABLE "Post" ADD FOREIGN KEY("authorId")REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE "Profile" ADD FOREIGN KEY("userId")REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; +``` + + + + + +**User** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :-------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `INTEGER` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `name` | `TEXT` | No | No | No | - | +| `email` | `TEXT` | No | No | **βœ”οΈ** | - | + +**Post** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :------------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `INTEGER` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `createdAt` | `TIMESTAMP` | No | No | **βœ”οΈ** | `now()` | +| `updatedAt` | `TIMESTAMP` | No | No | **βœ”οΈ** | | +| `title` | `VARCHAR(255)` | No | No | **βœ”οΈ** | - | +| `content` | `TEXT` | No | No | No | - | +| `published` | `BOOLEAN` | No | No | **βœ”οΈ** | `false` | +| `authorId` | `INTEGER` | No | **βœ”οΈ** | **βœ”οΈ** | - | + +**Profile** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :-------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `INTEGER` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `bio` | `TEXT` | No | No | No | - | +| `userId` | `INTEGER` | No | **βœ”οΈ** | **βœ”οΈ** | - | + + + + + + + + + + + + + +```sql +CREATE TABLE `Post` ( + `id` int NOT NULL AUTO_INCREMENT, + `createdAt` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + `updatedAt` datetime(3) NOT NULL, + `title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `content` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `published` tinyint(1) NOT NULL DEFAULT '0', + `authorId` int NOT NULL, + PRIMARY KEY (`id`), + KEY `Post_authorId_idx` (`authorId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE `Profile` ( + `id` int NOT NULL AUTO_INCREMENT, + `bio` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `userId` int NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `Profile_userId_key` (`userId`), + KEY `Profile_userId_idx` (`userId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE `User` ( + `id` int NOT NULL AUTO_INCREMENT, + `email` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, + `name` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `User_email_key` (`email`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +``` + + + + + +**User** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :------------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `int` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `name` | `varchar(191)` | No | No | No | - | +| `email` | `varchar(191)` | No | No | **βœ”οΈ** | - | + +**Post** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :------------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `int` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `createdAt` | `datetime(3)` | No | No | **βœ”οΈ** | `now()` | +| `updatedAt` | `datetime(3)` | No | No | **βœ”οΈ** | | +| `title` | `varchar(255)` | No | No | **βœ”οΈ** | - | +| `content` | `varchar(191)` | No | No | No | - | +| `published` | `tinyint(1)` | No | No | **βœ”οΈ** | `false` | +| `authorId` | `int` | No | No | **βœ”οΈ** | - | + +**Profile** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :------------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `int` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `bio` | `varchar(191)` | No | No | No | - | +| `userId` | `int` | No | No | **βœ”οΈ** | - | + + + + + + + + + + + + + +```sql +BEGIN TRY + +BEGIN TRAN; + +-- CreateTable +CREATE TABLE [dbo].[Post] ( + [id] INT NOT NULL IDENTITY(1,1), + [createdAt] DATETIME2 NOT NULL CONSTRAINT [Post_createdAt_df] DEFAULT CURRENT_TIMESTAMP, + [updatedAt] DATETIME2 NOT NULL, + [title] VARCHAR(255) NOT NULL, + [content] NVARCHAR(1000), + [published] BIT NOT NULL CONSTRAINT [Post_published_df] DEFAULT 0, + [authorId] INT NOT NULL, + CONSTRAINT [Post_pkey] PRIMARY KEY ([id]) +); + +-- CreateTable +CREATE TABLE [dbo].[Profile] ( + [id] INT NOT NULL IDENTITY(1,1), + [bio] NVARCHAR(1000), + [userId] INT NOT NULL, + CONSTRAINT [Profile_pkey] PRIMARY KEY ([id]), + CONSTRAINT [Profile_userId_key] UNIQUE ([userId]) +); + +-- CreateTable +CREATE TABLE [dbo].[User] ( + [id] INT NOT NULL IDENTITY(1,1), + [email] NVARCHAR(1000) NOT NULL, + [name] NVARCHAR(1000), + CONSTRAINT [User_pkey] PRIMARY KEY ([id]), + CONSTRAINT [User_email_key] UNIQUE ([email]) +); + +-- AddForeignKey +ALTER TABLE [dbo].[Post] ADD CONSTRAINT [Post_authorId_fkey] FOREIGN KEY ([authorId]) REFERENCES [dbo].[User]([id]) ON DELETE NO ACTION ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE [dbo].[Profile] ADD CONSTRAINT [Profile_userId_fkey] FOREIGN KEY ([userId]) REFERENCES [dbo].[User]([id]) ON DELETE NO ACTION ON UPDATE CASCADE; + +COMMIT TRAN; + +END TRY +BEGIN CATCH + +IF @@TRANCOUNT > 0 +BEGIN + ROLLBACK TRAN; +END; +THROW + +END CATCH +``` + + + + + +**User** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :--------------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `INT` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `name` | `NVARCHAR(1000)` | No | No | No | - | +| `email` | `NVARCHAR(1000)` | No | No | **βœ”οΈ** | - | + +**Post** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :--------------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `INT` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `createdAt` | `DATETIME2` | No | No | **βœ”οΈ** | `now()` | +| `updatedAt` | `DATETIME2` | No | No | **βœ”οΈ** | | +| `title` | `VARCHAR(255)` | No | No | **βœ”οΈ** | - | +| `content` | `NVARCHAR(1000)` | No | No | No | - | +| `published` | `BIT` | No | No | **βœ”οΈ** | `false` | +| `authorId` | `INT` | No | **βœ”οΈ** | **βœ”οΈ** | - | + +**Profile** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :--------------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `INT` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `bio` | `NVARCHAR(1000)` | No | No | No | - | +| `userId` | `INT` | No | **βœ”οΈ** | **βœ”οΈ** | - | + + + + + + + + + +In this guide, you'll use [Prisma Migrate](/orm/prisma-migrate) to create the tables in your database. Add the following Prisma data model to your Prisma schema in `prisma/schema.prisma`: + +```prisma file=prisma/schema.prisma copy +model Post { + id BigInt @id @default(sequence()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + title String @db.VarChar(255) + content String? + published Boolean @default(false) + author User @relation(fields: [authorId], references: [id]) + authorId BigInt +} + +model Profile { + id BigInt @id @default(sequence()) + bio String? + user User @relation(fields: [userId], references: [id]) + userId BigInt @unique +} + +model User { + id BigInt @id @default(sequence()) + email String @unique + name String? + posts Post[] + profile Profile? +} +``` + +To map your data model to the database schema, you need to use the `prisma migrate` CLI commands: + +```terminal +npx prisma migrate dev --name init +``` + +This command does two things: + +1. It creates a new SQL migration file for this migration +1. It runs the SQL migration file against the database + +> **Note**: `generate` is called under the hood by default, after running `prisma migrate dev`. If the `prisma-client-js` generator is defined in your schema, this will check if `@prisma/client` is installed and install it if it's missing. + +Great, you now created three tables in your database with Prisma Migrate πŸš€ + + + + + + + + + Connect your database + + + + Install Prisma Client + + + + + + + + + + + + Connect your database + + + + Install Prisma Client + + + + + + + + + + + + Connect your database + + + + Install Prisma Client + + + + + + + + + + + + Connect your database + + + + Install Prisma Client + + + + + + + + + + + + Connect your database + + + + Install Prisma Client + + + + + + + + + + + + Connect your database + + + + Install Prisma Client + + + + + + + + + + + + Connect your database + + + + Install Prisma Client + + + + + + + + + + + + Connect your database + + + + Install Prisma Client + + + + + + + + + + + + Connect your database + + + + Install Prisma Client + + + + + + + + + + + + Connect your database + + + + Install Prisma Client + + + + + diff --git a/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/110-relational-databases/200-install-prisma-client.mdx b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/110-relational-databases/200-install-prisma-client.mdx new file mode 100644 index 0000000000..4aaadb8bb7 --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/110-relational-databases/200-install-prisma-client.mdx @@ -0,0 +1,282 @@ +--- +title: 'Install Prisma Client' +metaTitle: 'Install Prisma Client' +metaDescription: 'Install and generate Prisma Client in your project' +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['postgresql', 'mysql', 'sqlserver', 'planetscale', 'cockroachdb'] +toc: false +--- + +## Install and generate Prisma Client + +To get started with Prisma Client, you need to install the `@prisma/client` package: + +```terminal copy +npm install @prisma/client +``` + +The install command invokes `prisma generate` for you which reads your Prisma schema and generates a version of Prisma Client that is _tailored_ to your models. + +![Install and generate Prisma Client](/img/getting-started/prisma-client-install-and-generate.png) + +Whenever you update your Prisma schema, you will have to update your database schema using either `prisma migrate dev` or `prisma db push`. This will keep your database schema in sync with your Prisma schema. The commands will also regenerate Prisma Client. + + + + + + + Using Prisma Migrate + + + + Querying the database + + + + + + + + + + + + Using Prisma Migrate + + + + Querying the database + + + + + + + + + + + + Using Prisma Migrate + + + + Querying the database + + + + + + + + + + + + Using Prisma Migrate + + + + Querying the database + + + + + + + + + + + + Using Prisma Migrate + + + + Querying the database + + + + + + + + + + + + Using Prisma Migrate + + + + Querying the database + + + + + + + + + + + + Using Prisma Migrate + + + + Querying the database + + + + + + + + + + + + Creating the database schema + + + + Querying the database + + + + + + + + + + + + Using Prisma Migrate + + + + Querying the database + + + + + + + + + + + + Using Prisma Migrate + + + + Querying the database + + + + + diff --git a/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/110-relational-databases/250-querying-the-database.mdx b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/110-relational-databases/250-querying-the-database.mdx new file mode 100644 index 0000000000..5b85245b3e --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/110-relational-databases/250-querying-the-database.mdx @@ -0,0 +1,605 @@ +--- +title: 'Querying the database' +metaTitle: 'Querying the database' +metaDescription: 'Write data to and query the database' +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['postgresql', 'mysql', 'sqlserver', 'planetscale', 'cockroachdb'] +toc: false +--- + +## Write your first query with Prisma Client + +Now that you have generated [Prisma Client](/orm/prisma-client), you can start writing queries to read and write data in your database. For the purpose of this guide, you'll use a plain Node.js script to explore some basic features of Prisma Client. + + + +Create a new file named `index.ts` and add the following code to it: + +```js file=index.ts copy +import { PrismaClient } from '@prisma/client' + +const prisma = new PrismaClient() + +async function main() { + // ... you will write your Prisma Client queries here +} + +main() + .then(async () => { + await prisma.$disconnect() + }) + .catch(async (e) => { + console.error(e) + await prisma.$disconnect() + process.exit(1) + }) +``` + + + + + +Create a new file named `index.js` and add the following code to it: + +```js file=index.js copy +const { PrismaClient } = require('@prisma/client') + +const prisma = new PrismaClient() + +async function main() { + // ... you will write your Prisma Client queries here +} + +main() + .then(async () => { + await prisma.$disconnect() + }) + .catch(async (e) => { + console.error(e) + await prisma.$disconnect() + process.exit(1) + }) +``` + + + +Here's a quick overview of the different parts of the code snippet: + +1. Import the `PrismaClient` constructor from the `@prisma/client` node module +1. Instantiate `PrismaClient` +1. Define an `async` function named `main` to send queries to the database +1. Call the `main` function +1. Close the database connections when the script terminates + +Inside the `main` function, add the following query to read all `User` records from the database and print the result: + + + +```ts file=index.ts highlight=3,4;add +async function main() { + // ... you will write your Prisma Client queries here + const allUsers = await prisma.user.findMany() + console.log(allUsers) +} +``` + + + + + +```js file=index.js highlight=2;delete|3,4;add +async function main() { + // ... you will write your Prisma Client queries here + const allUsers = await prisma.user.findMany() + console.log(allUsers) +} +``` + + + +Now run the code with this command: + + + +```terminal copy +npx ts-node index.ts +``` + + + + + +```terminal copy +node index.js +``` + + + +This should print an empty array because there are no `User` records in the database yet: + +```json no-lines +[] +``` + +## Write data into the database + +The `findMany` query you used in the previous section only _reads_ data from the database (although it was still empty). In this section, you'll learn how to write a query to _write_ new records into the `Post` and `User` tables. + +Adjust the `main` function to send a `create` query to the database: + + + +```ts file=index.ts highlight=2-21;add copy +async function main() { + await prisma.user.create({ + data: { + name: 'Alice', + email: 'alice@prisma.io', + posts: { + create: { title: 'Hello World' }, + }, + profile: { + create: { bio: 'I like turtles' }, + }, + }, + }) + + const allUsers = await prisma.user.findMany({ + include: { + posts: true, + profile: true, + }, + }) + console.dir(allUsers, { depth: null }) +} +``` + + + + + +```js file=index.js highlight=2-21;add copy +async function main() { + await prisma.user.create({ + data: { + name: 'Alice', + email: 'alice@prisma.io', + posts: { + create: { title: 'Hello World' }, + }, + profile: { + create: { bio: 'I like turtles' }, + }, + }, + }) + + const allUsers = await prisma.user.findMany({ + include: { + posts: true, + profile: true, + }, + }) + console.dir(allUsers, { depth: null }) +} +``` + + + +This code creates a new `User` record together with new `Post` and `Profile` records using a [nested write](/orm/prisma-client/queries/relation-queries#nested-writes) query. The `User` record is connected to the two other ones via the `Post.author` ↔ `User.posts` and `Profile.user` ↔ `User.profile` [relation fields](/orm/prisma-schema/data-model/relations#relation-fields) respectively. + +Notice that you're passing the [`include`](/orm/prisma-client/queries/select-fields#include-relations-and-select-relation-fields) option to `findMany` which tells Prisma Client to include the `posts` and `profile` relations on the returned `User` objects. + +Run the code with this command: + + + +```terminal copy +npx ts-node index.ts +``` + + + + + +```terminal copy +node index.js +``` + + + +The output should look similar to this: + +```js no-lines +[ + { + email: 'alice@prisma.io', + id: 1, + name: 'Alice', + posts: [ + { + content: null, + createdAt: 2020-03-21T16:45:01.246Z, + updatedAt: 2020-03-21T16:45:01.246Z, + id: 1, + published: false, + title: 'Hello World', + authorId: 1, + } + ], + profile: { + bio: 'I like turtles', + id: 1, + userId: 1, + } + } +] +``` + + + +Also note that `allUsers` is _statically typed_ thanks to [Prisma Client's generated types](/orm/prisma-client/type-safety/operating-against-partial-structures-of-model-types). You can observe the type by hovering over the `allUsers` variable in your editor. It should be typed as follows: + +```ts no-lines +const allUsers: (User & { + posts: Post[] +})[] + +export type Post = { + id: number + title: string + content: string | null + published: boolean + authorId: number | null +} +``` + + + +The query added new records to the `User` and the `Post` tables: + +**User** + +| **id** | **email** | **name** | +| :----- | :------------------ | :-------- | +| `1` | `"alice@prisma.io"` | `"Alice"` | + +**Post** + +| **id** | **createdAt** | **updatedAt** | **title** | **content** | **published** | **authorId** | +| :----- | :------------------------- | :------------------------: | :-------------- | :---------- | :------------ | :----------- | +| `1` | `2020-03-21T16:45:01.246Z` | `2020-03-21T16:45:01.246Z` | `"Hello World"` | `null` | `false` | `1` | + +**Profile** + +| **id** | **bio** | **userId** | +| :----- | :----------------- | :--------- | +| `1` | `"I like turtles"` | `1` | + +> **Note**: The numbers in the `authorId` column on `Post` and `userId` column on `Profile` both reference the `id` column of the `User` table, meaning the `id` value `1` column therefore refers to the first (and only) `User` record in the database. + +Before moving on to the next section, you'll "publish" the `Post` record you just created using an `update` query. Adjust the `main` function as follows: + + + +```ts file=index.ts copy +async function main() { + const post = await prisma.post.update({ + where: { id: 1 }, + data: { published: true }, + }) + console.log(post) +} +``` + + + + + +```js file=index.js copy +async function main() { + const post = await prisma.post.update({ + where: { id: 1 }, + data: { published: true }, + }) + console.log(post) +} +``` + + + + + +Now run the code using the same command as before: + +```terminal copy +npx ts-node index.ts +``` + + + + + +Now run the code using the same command as before: + +```terminal copy +node index.js +``` + + + +You will see the following output: + +```js no-lines +{ + id: 1, + title: 'Hello World', + content: null, + published: true, + authorId: 1 +} +``` + +The `Post` record with an `id` of `1` now got updated in the database: + +**Post** + +| **id** | **title** | **content** | **published** | **authorId** | +| :----- | :-------------- | :---------- | :------------ | :----------- | +| `1` | `"Hello World"` | `null` | `true` | `1` | + +Fantastic, you just wrote new data into your database for the first time using Prisma Client πŸš€ + + + + + + + Install Prisma Client + + + + Next Steps + + + + + + + + + + + + Install Prisma Client + + + + Next Steps + + + + + + + + + + + + Install Prisma Client + + + + Next Steps + + + + + + + + + + + + Install Prisma Client + + + + Next Steps + + + + + + + + + + + + Install Prisma Client + + + + Next Steps + + + + + + + + + + + + Install Prisma Client + + + + Next Steps + + + + + + + + + + + + Install Prisma Client + + + + Next Steps + + + + + + + + + + + + Install Prisma Client + + + + Next Steps + + + + + + + + + + + + Install Prisma Client + + + + Next Steps + + + + + + + + + + + + Install Prisma Client + + + + Next Steps + + + + + diff --git a/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/110-relational-databases/300-next-steps.mdx b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/110-relational-databases/300-next-steps.mdx new file mode 100644 index 0000000000..0b87f7e32b --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/110-relational-databases/300-next-steps.mdx @@ -0,0 +1,106 @@ +--- +title: 'Next steps' +metaTitle: 'Next steps' +metaDescription: 'Next steps to take now that you have successfully added Prisma to your project' +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['postgresql', 'mysql', 'sqlserver', 'planetscale', 'cockroachdb'] +toc: false +--- + +## Next steps + +This section lists a number of potential next steps you can now take from here. Feel free to explore these or read the [Introduction](/orm/overview/introduction/what-is-prisma) page to get a high-level overview of Prisma. + +### Continue exploring the Prisma Client API + +You can send a variety of queries with the Prisma Client API. Check out the [API reference](/orm/prisma-client) and use your existing database setup from this guide to try them out. + +:::tip + +You can use your editor's auto-completion feature to learn about the different API calls and the arguments it takes. Auto-completion is commonly invoked by hitting CTRL+SPACE on your keyboard. + +::: + +
+Expand for more Prisma Client API examples + +Here are a few suggestions for a number of more queries you can send with Prisma Client: + +**Filter all `Post` records that contain `"hello"`** + +```js +const filteredPosts = await prisma.post.findMany({ + where: { + OR: [{ title: { contains: 'hello' } }, { content: { contains: 'hello' } }], + }, +}) +``` + +**Create a new `Post` record and connect it to an existing `User` record** + +```js +const post = await prisma.post.create({ + data: { + title: 'Join us for Prisma Day 2020', + author: { + connect: { email: 'alice@prisma.io' }, + }, + }, +}) +``` + +**Use the fluent relations API to retrieve the `Post` records of a `User` by traversing the relations** + +```js +const posts = await prisma.profile + .findUnique({ + where: { id: 1 }, + }) + .user() + .posts() +``` + +**Delete a `User` record** + +```js +const deletedUser = await prisma.user.delete({ + where: { email: 'sarah@prisma.io' }, +}) +``` + +
+ +### Explore the data in Prisma Studio + +Prisma Studio is a visual editor for the data in your database. Run `npx prisma studio` in your terminal. + +### Try a Prisma example + +The [`prisma-examples`](https://github.com/prisma/prisma-examples/) repository contains a number of ready-to-run examples: + + + + + +| Demo | Stack | Description | +| :------------------------------------------------------------------------------------------------------------------ | :----------- | --------------------------------------------------------------------------------------------------- | +| [`rest-nextjs-api-routes`](https://github.com/prisma/prisma-examples/tree/latest/typescript/rest-nextjs-api-routes) | Fullstack | Simple [Next.js](https://nextjs.org/) app (React) with a REST API | +| [`graphql-nextjs`](https://github.com/prisma/prisma-examples/tree/latest/typescript/graphql-nextjs) | Fullstack | Simple [Next.js](https://nextjs.org/) app (React) with a GraphQL API | +| [`graphql-apollo-server`](https://github.com/prisma/prisma-examples/tree/latest/typescript/graphql) | Backend only | Simple GraphQL server based on [`apollo-server`](https://www.apollographql.com/docs/apollo-server/) | +| [`rest-express`](https://github.com/prisma/prisma-examples/tree/latest/typescript/rest-express) | Backend only | Simple REST API with Express.JS | +| [`grpc`](https://github.com/prisma/prisma-examples/tree/latest/typescript/grpc) | Backend only | Simple gRPC API | + + + + + +| Demo | Stack | Description | +| :---------------------------------------------------------------------------------------------------------------- | :----------- | :-------------------------------------------------------------------------------------------------- | +| [`rest-nextjs`](https://github.com/prisma/prisma-examples/tree/latest/javascript/rest-nextjs) | Fullstack | Simple [Next.js](https://nextjs.org/) app (React) with a REST API | +| [`graphql-apollo-server`](https://github.com/prisma/prisma-examples/tree/latest/javascript/graphql-apollo-server) | Backend only | Simple GraphQL server based on [`apollo-server`](https://www.apollographql.com/docs/apollo-server/) | +| [`rest-express`](https://github.com/prisma/prisma-examples/tree/latest/javascript/rest-express) | Backend only | Simple REST API with Express.JS | +| [`grpc`](https://github.com/prisma/prisma-examples/tree/latest/javascript/grpc) | Backend only | Simple gRPC API | + + + + diff --git a/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/110-relational-databases/index.mdx b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/110-relational-databases/index.mdx new file mode 100644 index 0000000000..c8cb90bda0 --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/110-relational-databases/index.mdx @@ -0,0 +1,300 @@ +--- +title: 'Relational databases' +metaTitle: 'Start from scratch with relational databases (15 min)' +metaDescription: 'Learn how to create a new Node.js or TypeScript project from scratch by connecting Prisma to your relational database and generating a Prisma Client for database access.' +duration: '15 min' +toc: false +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['postgresql', 'mysql', 'sqlserver', 'planetscale', 'cockroachdb'] +--- + + + +Learn how to create a new Node.js or TypeScript project from scratch by connecting Prisma to your database and generating a Prisma Client for database access. The following tutorial introduces you to the [Prisma CLI](/orm/tools/prisma-cli), [Prisma Client](/orm/prisma-client), and [Prisma Migrate](/orm/prisma-migrate). + + + +## Prerequisites + +In order to successfully complete this guide, you need: + + + +- [Node.js](https://nodejs.org/en/) installed on your machine +- a [PostgreSQL](https://www.postgresql.org/) database server running + + + + + +- [Node.js](https://nodejs.org/en/) installed on your machine +- a [CockroachDB](https://www.cockroachlabs.com/) database server running + + + + + +- [Node.js](https://nodejs.org/en/) installed on your machine +- a [MySQL](https://www.mysql.com/) database server running + + + + + +- [Node.js](https://nodejs.org/en/) installed on your machine +- a [PlanetScale](https://www.planetscale.com/) database server running + + + +This tutorial will also assume that you can push to the `main` branch of your database. Do not do this if your `main` branch has been promoted to production. + + + + + + + +- [Node.js](https://nodejs.org/en/) installed on your machine +- A [Microsoft SQL Server](https://docs.microsoft.com/en-us/sql/?view=sql-server-ver15) database + - [Microsoft SQL Server on Linux for Docker](/orm/overview/databases/sql-server/sql-server-docker) + - [Microsoft SQL Server on Windows (local)](/orm/overview/databases/sql-server/sql-server-local) + + + +> See [System requirements](/orm/reference/system-requirements) for exact version requirements. + +Make sure you have your database [connection URL](/orm/reference/connection-urls) at hand. If you don't have a database server running and just want to explore Prisma, check out the [Quickstart](/getting-started/quickstart). + +## Create project setup + +As a first step, create a project directory and navigate into it: + +```terminal copy +mkdir hello-prisma +cd hello-prisma +``` + + + +Next, initialize a TypeScript project and add the Prisma CLI as a development dependency to it: + +```terminal copy +npm init -y +npm install prisma typescript ts-node @types/node --save-dev +``` + +This creates a `package.json` with an initial setup for your TypeScript app. + +Next, initialize TypeScript: + +```terminal copy +npx tsc --init +``` + + + + + +Next, initialize a Node.js project and add the Prisma CLI as a development dependency to it: + +```terminal copy +npm init -y +npm install prisma --save-dev +``` + +This creates a `package.json` with an initial setup for a Node.js app. + + + + + +See [installation instructions](/orm/tools/prisma-cli#installation) to learn how to install Prisma using a different package manager. + + + +You can now invoke the Prisma CLI by prefixing it with `npx`: + +```terminal +npx prisma +``` + +Next, set up your Prisma project by creating your [Prisma schema](/orm/prisma-schema) file with the following command: + +```terminal copy +npx prisma init +``` + +This command does two things: + +- creates a new directory called `prisma` that contains a file called `schema.prisma`, which contains the Prisma schema with your database connection variable and schema models +- creates the [`.env` file](/orm/more/development-environment/environment-variables/env-files) in the root directory of the project, which is used for defining environment variables (such as your database connection) + + + + + + + Connect your database + + + + + + + + + + + + Connect your database + + + + + + + + + + + + Connect your database + + + + + + + + + + + + Connect your database + + + + + + + + + + + + Connect your database + + + + + + + + + + + + Connect your database + + + + + + + + + + + + Connect your database + + + + + + + + + + + + Connect your database + + + + + + + + + + + + Connect your database + + + + + + + + + + + + Connect your database + + + + + diff --git a/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/120-mongodb/100-connect-your-database.mdx b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/120-mongodb/100-connect-your-database.mdx new file mode 100644 index 0000000000..9edea9c598 --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/120-mongodb/100-connect-your-database.mdx @@ -0,0 +1,93 @@ +--- +title: 'Connect your database (MongoDB)' +metaTitle: 'Connect your database' +metaDescription: 'Connect your database to your project' +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['mongodb'] +toc: false +--- + +## Connect your database + +To connect your database, you need to set the `url` field of the `datasource` block in your Prisma schema to your database [connection URL](/orm/reference/connection-urls): + +```prisma file=prisma/schema.prisma +datasource db { + provider = "mongodb" + url = env("DATABASE_URL") +} +``` + +In this case, the `url` is [set via an environment variable](/orm/more/development-environment/environment-variables) which is defined in `.env` (the example uses a [MongoDB Atlas](https://www.mongodb.com/cloud/atlas) URL): + +```bash file=.env +DATABASE_URL="mongodb+srv://test:test@cluster0.ns1yp.mongodb.net/myFirstDatabase" +``` + +You now need to adjust the connection URL to point to your own database. + +The [format of the connection URL](/orm/reference/connection-urls) for your database depends on the database you use. For MongoDB, it looks as follows (the parts spelled all-uppercased are _placeholders_ for your specific connection details): + +```no-lines +mongodb://USERNAME:PASSWORD@HOST:PORT/DATABASE +``` + +Here's a short explanation of each component: + +- `USERNAME`: The name of your database user +- `PASSWORD`: The password for your database user +- `HOST`: The host where a [`mongod`](https://docs.mongodb.com/manual/reference/program/mongod/#mongodb-binary-bin.mongod) (or [`mongos`](https://docs.mongodb.com/manual/reference/program/mongos/#mongodb-binary-bin.mongos)) instance is running +- `PORT`: The port where your database server is running (typically `27017` for MongoDB) +- `DATABASE`: The name of the database + + + + + + + Installation + + + + Creating the Prisma schema + + + + + + + + + + + + Installation + + + + Creating the Prisma schema + + + + + diff --git a/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/120-mongodb/125-creating-the-prisma-schema.mdx b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/120-mongodb/125-creating-the-prisma-schema.mdx new file mode 100644 index 0000000000..ece8f719b7 --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/120-mongodb/125-creating-the-prisma-schema.mdx @@ -0,0 +1,114 @@ +--- +title: 'Creating the Prisma schema' +metaTitle: 'Creating the Prisma schema' +metaDescription: 'Update the Prisma schema for MongoDB' +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['mongodb'] +toc: false +--- + +## Update the Prisma schema + +Open the `prisma/schema.prisma` file and replace the default contents with the following: + +```prisma file=prisma/schema.prisma +datasource db { + provider = "mongodb" + url = env("DATABASE_URL") +} + +generator client { + provider = "prisma-client-js" +} + +model Post { + id String @id @default(auto()) @map("_id") @db.ObjectId + slug String @unique + title String + body String + author User @relation(fields: [authorId], references: [id]) + authorId String @db.ObjectId + comments Comment[] +} + +model User { + id String @id @default(auto()) @map("_id") @db.ObjectId + email String @unique + name String? + address Address? + posts Post[] +} + +model Comment { + id String @id @default(auto()) @map("_id") @db.ObjectId + comment String + post Post @relation(fields: [postId], references: [id]) + postId String @db.ObjectId +} + +// Address is an embedded document +type Address { + street String + city String + state String + zip String +} +``` + +There are also a number of subtle differences in how the schema is setup when compared to relational databases like PostgreSQL. + +For example, the underlying `ID` field name is always `_id` and must be mapped with `@map("_id")`. + +For more information check out the [MongoDB schema reference](/orm/reference/prisma-schema-reference#mongodb-2). + + + + + + + Connect your database + + + + Install Prisma Client + + + + + + + + + + + + Connect your database + + + + Install Prisma Client + + + + + diff --git a/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/120-mongodb/200-install-prisma-client.mdx b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/120-mongodb/200-install-prisma-client.mdx new file mode 100644 index 0000000000..c3ae612967 --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/120-mongodb/200-install-prisma-client.mdx @@ -0,0 +1,74 @@ +--- +title: 'Install Prisma Client' +metaTitle: 'Install Prisma Client' +metaDescription: 'Install and generate Prisma Client in your project' +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['mongodb'] +toc: false +--- + +## Install and generate Prisma Client + +To get started with Prisma Client, you need to install the `@prisma/client` package: + +```terminal copy +npm install @prisma/client +``` + +The install command invokes `prisma generate` for you which reads your Prisma schema and generates a version of Prisma Client that is _tailored_ to your models. + +![Install and generate Prisma Client](/img/getting-started/prisma-client-install-and-generate.png) + +Whenever you update your Prisma schema, you will need to run the `prisma db push` command to create new indexes and regenerate Prisma Client. + + + + + + + Creating the Prisma schema + + + + Querying the database + + + + + + + + + + + + Creating the Prisma schema + + + + Querying the database + + + + + diff --git a/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/120-mongodb/250-querying-the-database.mdx b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/120-mongodb/250-querying-the-database.mdx new file mode 100644 index 0000000000..d650cc2032 --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/120-mongodb/250-querying-the-database.mdx @@ -0,0 +1,425 @@ +--- +title: 'Querying the database' +metaTitle: 'Querying the database' +metaDescription: 'Write data to and query the database' +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['mongodb'] +toc: false +--- + +## Write your first query with Prisma Client + +Now that you have generated Prisma Client, you can start writing queries to read and write data in your database. For the purpose of this guide, you'll use a plain Node.js script to explore some basic features of Prisma Client. + + + +Create a new file named `index.ts` and add the following code to it: + +```js file=index.ts copy +import { PrismaClient } from '@prisma/client' + +const prisma = new PrismaClient() + +async function main() { + // ... you will write your Prisma Client queries here +} + +main() + .catch(async (e) => { + console.error(e) + process.exit(1) + }) + .finally(async () => { + await prisma.$disconnect() + }) +``` + + + + + +Create a new file named `index.js` and add the following code to it: + +```js file=index.js copy +const { PrismaClient } = require('@prisma/client') + +const prisma = new PrismaClient() + +async function main() { + // ... you will write your Prisma Client queries here +} + +main() + .then(async () => { + await prisma.$disconnect() + }) + .catch(async (e) => { + console.error(e) + await prisma.$disconnect() + process.exit(1) + }) +``` + + + +Here's a quick overview of the different parts of the code snippet: + +1. Import the `PrismaClient` constructor from the `@prisma/client` node module +1. Instantiate `PrismaClient` +1. Define an `async` function named `main` to send queries to the database +1. Connect to the database +1. Call the `main` function +1. Close the database connections when the script terminates + +Inside the `main` function, add the following query to read all `User` records from the database and print the result: + + + +```ts file=index.ts +async function main() { + // ... you will write your Prisma Client queries here ++ const allUsers = await prisma.user.findMany() ++ console.log(allUsers) +} +``` + + + + + +```js file=index.js +async function main() { +- // ... you will write your Prisma Client queries here ++ const allUsers = await prisma.user.findMany() ++ console.log(allUsers) +} +``` + + + +Now run the code with this command: + + + +```terminal copy +npx ts-node index.ts +``` + + + + + +```terminal copy +node index.js +``` + + + +This should print an empty array because there are no `User` records in the database yet: + +```json no-lines +[] +``` + +## Write data into the database + +The `findMany` query you used in the previous section only _reads_ data from the database (although it was still empty). In this section, you'll learn how to write a query to _write_ new records into the `Post`, `User` and `Comment` tables. + +Adjust the `main` function to send a `create` query to the database: + + + +```ts file=index.ts highlight=2-21;add copy +async function main() { + await prisma.user.create({ + data: { + name: 'Rich', + email: 'hello@prisma.com', + posts: { + create: { + title: 'My first post', + body: 'Lots of really interesting stuff', + slug: 'my-first-post', + }, + }, + }, + }) + + const allUsers = await prisma.user.findMany({ + include: { + posts: true, + }, + }) + console.dir(allUsers, { depth: null }) +} +``` + + + + + +```js file=index.js highlight=2-21;add copy +async function main() { + await prisma.user.create({ + data: { + name: 'Rich', + email: 'hello@prisma.com', + posts: { + create: { + title: 'My first post', + body: 'Lots of really interesting stuff', + slug: 'my-first-post', + }, + }, + }, + }) + + const allUsers = await prisma.user.findMany({ + include: { + posts: true, + }, + }) + console.dir(allUsers, { depth: null }) +} +``` + + + +This code creates a new `User` record together with a new `Post` using a [nested write](/orm/prisma-client/queries/relation-queries#nested-writes) query. The `User` record is connected to the other one via the `Post.author` ↔ `User.posts` [relation fields](/orm/prisma-schema/data-model/relations#relation-fields) respectively. + +Notice that you're passing the [`include`](/orm/prisma-client/queries/select-fields#include-relations-and-select-relation-fields) option to `findMany` which tells Prisma Client to include the `posts` relations on the returned `User` objects. + +Run the code with this command: + + + +```terminal copy +npx ts-node index.ts +``` + + + + + +```terminal copy +node index.js +``` + + + +The output should look similar to this: + +```json5 no-lines +[ + { + id: '60cc9b0e001e3bfd00a6eddf', + email: 'hello@prisma.com', + name: 'Rich', + address: null, + posts: [ + { + id: '60cc9bad005059d6007f45dd', + slug: 'my-first-post', + title: 'My first post', + body: 'Lots of really interesting stuff', + userId: '60cc9b0e001e3bfd00a6eddf', + }, + ], + }, +] +``` + + + +Also note that `allUsers` is _statically typed_ thanks to [Prisma Client's generated types](/orm/prisma-client/type-safety/operating-against-partial-structures-of-model-types). You can observe the type by hovering over the `allUsers` variable in your editor. It should be typed as follows: + +```ts no-lines +const allUsers: (User & { + posts: Post[] +})[] + +export type Post = { + id: number + title: string + body: string | null + published: boolean + authorId: number | null +} +``` + + + +The query added new records to the `User` and the `Post` tables: + +**User** + +| **id** | **email** | **name** | +| :------------------------- | :------------------- | :------- | +| `60cc9b0e001e3bfd00a6eddf` | `"hello@prisma.com"` | `"Rich"` | + +**Post** + +| **id** | **createdAt** | **title** | **content** | **published** | **authorId** | +| :------------------------- | :------------------------- | :---------------- | :--------------------------------- | :------------ | :------------------------- | +| `60cc9bad005059d6007f45dd` | `2020-03-21T16:45:01.246Z` | `"My first post"` | `Lots of really interesting stuff` | `false` | `60cc9b0e001e3bfd00a6eddf` | + +> **Note**: The unique IDs in the `authorId` column on `Post` reference the `id` column of the `User` table, meaning the `id` value `60cc9b0e001e3bfd00a6eddf` column therefore refers to the first (and only) `User` record in the database. + +Before moving on to the next section, you'll add a couple of comments to the `Post` record you just created using an `update` query. Adjust the `main` function as follows: + + + +```ts file=index.ts copy +async function main() { + await prisma.post.update({ + where: { + slug: 'my-first-post', + }, + data: { + comments: { + createMany: { + data: [ + { comment: 'Great post!' }, + { comment: "Can't wait to read more!" }, + ], + }, + }, + }, + }) + const posts = await prisma.post.findMany({ + include: { + comments: true, + }, + }) + + console.dir(posts, { depth: Infinity }) +} +``` + + + + + +```js file=index.js copy +async function main() { + await prisma.post.update({ + where: { + slug: 'my-first-post', + }, + data: { + comments: { + createMany: { + data: [ + { comment: 'Great post!' }, + { comment: "Can't wait to read more!" }, + ], + }, + }, + }, + }) + const posts = await prisma.post.findMany({ + include: { + comments: true, + }, + }) + + console.dir(posts, { depth: Infinity }) +} +``` + + + + + +Now run the code using the same command as before: + +```terminal copy +npx ts-node index.ts +``` + + + + + +Now run the code using the same command as before: + +```terminal copy +node index.js +``` + + + +You will see the following output: + +```json5 no-lines +[ + { + id: '60cc9bad005059d6007f45dd', + slug: 'my-first-post', + title: 'My first post', + body: 'Lots of really interesting stuff', + userId: '60cc9b0e001e3bfd00a6eddf', + comments: [ + { + id: '60cca420008a21d800578793', + postId: '60cca40300af8bf000f6ca99', + comment: 'Great post!', + }, + { + id: '60cca420008a21d800578794', + postId: '60cca40300af8bf000f6ca99', + comment: "Can't wait to try this!", + }, + ], + }, +] +``` + +Fantastic, you just wrote new data into your database for the first time using Prisma Client πŸš€ + + + + + + + Install Prisma Client + + + + Next Steps + + + + + + + + + + + + Install Prisma Client + + + + Next Steps + + + + + diff --git a/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/120-mongodb/300-next-steps.mdx b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/120-mongodb/300-next-steps.mdx new file mode 100644 index 0000000000..3d796c921c --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/120-mongodb/300-next-steps.mdx @@ -0,0 +1,108 @@ +--- +title: 'Next steps' +metaTitle: 'Next steps' +metaDescription: 'Next steps to take now that you have successfully added Prisma to your project' +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['mongodb'] +toc: false +--- + +## Next steps + +This section lists a number of potential next steps you can now take from here. Feel free to explore these or read the [Introduction](/orm/overview/introduction/what-is-prisma) page to get a high-level overview of Prisma. + +### Continue exploring the Prisma Client API + +You can send a variety of queries with the Prisma Client API. Check out the [API reference](/orm/prisma-client) and use your existing database setup from this guide to try them out. + +:::tip + +You can use your editor's auto-completion feature to learn about the different API calls and the arguments it takes. Auto-completion is commonly invoked by hitting CTRL+SPACE on your keyboard. + +::: + +
+Expand for more Prisma Client API examples + +Here are a few suggestions for a number of more queries you can send with Prisma Client: + +**Filter all `Post` records that contain `"hello"`** + +```js +const filteredPosts = await prisma.post.findMany({ + where: { + OR: [{ title: { contains: 'hello' } }, { body: { contains: 'hello' } }], + }, +}) +``` + +**Create a new `Post` record and connect it to an existing `User` record** + +```js +const post = await prisma.post.create({ + data: { + title: 'Join us for Prisma Day 2020', + slug: 'prisma-day-2020', + body: 'A conference on modern application development and databases.', + user: { + connect: { email: 'hello@prisma.com' }, + }, + }, +}) +``` + +**Use the fluent relations API to retrieve the `Post` records of a `User` by traversing the relations** + +```js +const user = await prisma.comment + .findUnique({ + where: { id: '60ff4e9500acc65700ebf470' }, + }) + .post() + .user() +``` + +**Delete a `User` record** + +```js +const deletedUser = await prisma.user.delete({ + where: { email: 'sarah@prisma.io' }, +}) +``` + +
+ +### Explore the data in Prisma Studio + +Prisma Studio is a visual editor for the data in your database. Run `npx prisma studio` in your terminal. + +### Try a Prisma example + +The [`prisma-examples`](https://github.com/prisma/prisma-examples/) repository contains a number of ready-to-run examples: + + + + + +| Demo | Stack | Description | +| :------------------------------------------------------------------------------------------------------------------ | :----------- | --------------------------------------------------------------------------------------------------- | +| [`rest-nextjs-api-routes`](https://github.com/prisma/prisma-examples/tree/latest/typescript/rest-nextjs-api-routes) | Fullstack | Simple [Next.js](https://nextjs.org/) app (React) with a REST API | +| [`graphql-nextjs`](https://github.com/prisma/prisma-examples/tree/latest/typescript/graphql-nextjs) | Fullstack | Simple [Next.js](https://nextjs.org/) app (React) with a GraphQL API | +| [`graphql-apollo-server`](https://github.com/prisma/prisma-examples/tree/latest/typescript/graphql-apollo-server) | Backend only | Simple GraphQL server based on [`apollo-server`](https://www.apollographql.com/docs/apollo-server/) | +| [`rest-express`](https://github.com/prisma/prisma-examples/tree/latest/typescript/rest-express) | Backend only | Simple REST API with Express.JS | +| [`grpc`](https://github.com/prisma/prisma-examples/tree/latest/typescript/grpc) | Backend only | Simple gRPC API | + + + + + +| Demo | Stack | Description | +| :---------------------------------------------------------------------------------------------------------------- | :----------- | :-------------------------------------------------------------------------------------------------- | +| [`rest-nextjs`](https://github.com/prisma/prisma-examples/tree/latest/javascript/rest-nextjs) | Fullstack | Simple [Next.js](https://nextjs.org/) app (React) with a REST API | +| [`graphql-apollo-server`](https://github.com/prisma/prisma-examples/tree/latest/javascript/graphql-apollo-server) | Backend only | Simple GraphQL server based on [`apollo-server`](https://www.apollographql.com/docs/apollo-server/) | +| [`rest-express`](https://github.com/prisma/prisma-examples/tree/latest/javascript/rest-express) | Backend only | Simple REST API with Express.JS | +| [`grpc`](https://github.com/prisma/prisma-examples/tree/latest/javascript/grpc) | Backend only | Simple gRPC API | + + + + diff --git a/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/120-mongodb/index.mdx b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/120-mongodb/index.mdx new file mode 100644 index 0000000000..d85b9fab97 --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/120-mongodb/index.mdx @@ -0,0 +1,124 @@ +--- +title: 'MongoDB' +metaTitle: 'Start from scratch with MongoDB (15 min)' +metaDescription: 'Learn how to create a new Node.js or TypeScript project from scratch by connecting Prisma to your MongoDB database and generating a Prisma Client for database access.' +duration: '15 min' +toc: false +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['mongodb'] +--- + + + +Learn how to create a new Node.js or TypeScript project from scratch by connecting Prisma to your MongoDB database and generating a Prisma Client for database access. The following tutorial introduces you to the [Prisma CLI](/orm/tools/prisma-cli) and [Prisma Client](/orm/prisma-client). + + + +## Prerequisites + +In order to successfully complete this guide, you need: + +- [Node.js](https://nodejs.org/en/) installed on your machine +- Access to a MongoDB 4.2+ server with a replica set deployment. We recommend using [MongoDB Atlas](https://www.mongodb.com/cloud/atlas). + + + + The MongoDB database connector uses transactions to support nested writes. TransactionsΒ **require**Β aΒ [replica set](https://docs.mongodb.com/manual/tutorial/deploy-replica-set/)Β deployment. The easiest way to deploy a replica set is withΒ [Atlas](https://docs.atlas.mongodb.com/getting-started/). It's free to get started. + + + +Make sure you have your database [connection URL](/orm/reference/connection-urls) at hand. If you don't have a database server running and just want to explore Prisma, check out the [Quickstart](/getting-started/quickstart). + +> See [System requirements](/orm/reference/system-requirements) for exact version requirements. + +## Create project setup + +As a first step, create a project directory and navigate into it: + +```terminal copy +mkdir hello-prisma +cd hello-prisma +``` + + + +Next, initialize a TypeScript project and add the Prisma CLI as a development dependency to it: + +```terminal copy +npm init -y +npm install prisma typescript ts-node @types/node --save-dev +``` + +This creates a `package.json` with an initial setup for your TypeScript app. + +Next, initialize TypeScript: + +```terminal copy +npx tsc --init +``` + + + + + +Next, initialize a Node.js project and add the Prisma CLI as a development dependency to it: + +```terminal copy +npm init -y +npm install prisma --save-dev +``` + +This creates a `package.json` with an initial setup for a Node.js app. + + + +You can now invoke the Prisma CLI by prefixing it with `npx`: + +```terminal +npx prisma +``` + +Next, set up your Prisma project by creating your [Prisma schema](/orm/prisma-schema) file with the following command: + +```terminal copy +npx prisma init +``` + +This command does two things: + +- creates a new directory called `prisma` that contains a file called `schema.prisma`, which contains the Prisma schema with your database connection variable and schema models +- creates the [`.env` file](/orm/more/development-environment/environment-variables/env-files) in the root directory of the project, which is used for defining environment variables (such as your database connection) + + + + + + + Connect your database + + + + + + + + + + + + Connect your database + + + + + diff --git a/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/index.mdx b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/index.mdx new file mode 100644 index 0000000000..491ba8b0b5 --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/100-start-from-scratch/index.mdx @@ -0,0 +1,16 @@ +--- +title: 'Start from scratch' +metaTitle: 'Start from scratch with Prisma' +metaDescription: 'Learn how to create a new Node.js or TypeScript project from scratch by connecting Prisma to your database of choice and generating a Prisma Client for database access.' +toc: false +--- + + + +Start a fresh project from scratch with the following tutorials as they introduce you to the [Prisma CLI](/orm/tools/prisma-cli), [Prisma Client](/orm/prisma-client), and [Prisma Migrate](/orm/prisma-migrate). + + + +## In this section + + diff --git a/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/100-connect-your-database.mdx b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/100-connect-your-database.mdx new file mode 100644 index 0000000000..2f08d506a0 --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/100-connect-your-database.mdx @@ -0,0 +1,520 @@ +--- +title: 'Connect your database' +metaTitle: 'Connect your database' +metaDescription: 'Connect your database to your project' +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['postgresql', 'mysql', 'sqlserver', 'planetscale', 'cockroachdb'] +toc: false +--- + +## Connecting your database + +To connect your database, you need to set the `url` field of the `datasource` block in your Prisma schema to your database [connection URL](/orm/reference/connection-urls): + + + +```prisma file=prisma/schema.prisma +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} +``` + +In this case, the `url` is [set via an environment variable](/orm/more/development-environment/environment-variables) which is defined in `.env`: + +```bash file=.env +DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public" +``` + +You now need to adjust the connection URL to point to your own database. + +

Connection URL

+ +The [format of the connection URL](/orm/reference/connection-urls) for your database depends on the database you use. For PostgreSQL, it looks as follows (the parts spelled all-uppercased are _placeholders_ for your specific connection details): + +```no-lines +postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=SCHEMA +``` + +> **Note**: In most cases, you can use the [`postgres://` and `postgresql:// URI scheme designators interchangeably`](https://www.postgresql.org/docs/10/libpq-connect.html#id-1.7.3.8.3.6) - however, depending on how your database is hosted, you might need to be specific. + +If you're unsure what to provide for the `schema` parameter for a PostgreSQL connection URL, you can probably omit it. In that case, the default schema name `public` will be used. + +As an example, for a PostgreSQL database hosted on Heroku, the connection URL might look similar to this: + +```bash file=.env +DATABASE_URL="postgresql://opnmyfngbknppm:XXX@ec2-46-137-91-216.eu-west-1.compute.amazonaws.com:5432/d50rgmkqi2ipus?schema=hello-prisma" +``` + +When running PostgreSQL locally on macOS, your user and password as well as the database name _typically_ correspond to the current _user_ of your OS, e.g. assuming the user is called `janedoe`: + +```bash file=.env +DATABASE_URL="postgresql://janedoe:janedoe@localhost:5432/janedoe?schema=hello-prisma" +``` + +
+ + + +```prisma file=prisma/schema.prisma +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} +``` + +Note that the default schema created by `prisma init` uses PostgreSQL, so you first need to switch the `provider` to `mysql`: + +```prisma file=prisma/schema.prisma highlight=2;edit +datasource db { + provider = "mysql" + url = env("DATABASE_URL") +} +``` + +In this case, the `url` is [set via an environment variable](/orm/prisma-schema/overview#accessing-environment-variables-from-the-schema) which is defined in `.env`: + +```bash file=.env +DATABASE_URL="mysql://johndoe:randompassword@localhost:3306/mydb" +``` + +You now need to adjust the connection URL to point to your own database. + +

Connection URL

+ +The [format of the connection URL](/orm/reference/connection-urls) for your database typically depends on the database you use. For MySQL, it looks as follows (the parts spelled all-uppercased are _placeholders_ for your specific connection details): + +```no-lines +mysql://USER:PASSWORD@HOST:PORT/DATABASE +``` + +Here's a short explanation of each component: + +- `USER`: The name of your database user +- `PASSWORD`: The password for your database user +- `PORT`: The port where your database server is running (typically `3306` for MySQL) +- `DATABASE`: The name of the [database](https://dev.mysql.com/doc/refman/8.0/en/creating-database.html) + +As an example, for a MySQL database hosted on AWS RDS, the [connection URL](/orm/reference/connection-urls) might look similar to this: + +```bash file=.env +DATABASE_URL="mysql://johndoe:XXX@mysql–instance1.123456789012.us-east-1.rds.amazonaws.com:3306/mydb" +``` + +When running MySQL locally, your connection URL typically looks similar to this: + +```bash file=.env +DATABASE_URL="mysql://root:randompassword@localhost:3306/mydb" +``` + +
+ + + +```prisma file=prisma/schema.prisma +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} +``` + +Note that the default schema created by `prisma init` uses PostgreSQL as the `provider`. For PlanetScale, you need to edit the `datasource` block to use the `mysql` provider instead: + +```prisma file=prisma/schema.prisma highlight=2;edit +datasource db { + provider = "mysql" + url = env("DATABASE_URL") +} +``` + +You will also need to [set the relation mode type to `prisma`](/orm/prisma-schema/data-model/relations/relation-mode#emulate-relations-in-prisma-with-the-prisma-relation-mode) in the `datasource` block: + +```prisma file=schema.prisma highlight=4;add +datasource db { + provider = "mysql" + url = env("DATABASE_URL") + relationMode = "prisma" +} +``` + +The `url` is [set via an environment variable](/orm/prisma-schema/overview#accessing-environment-variables-from-the-schema) which is defined in `.env`: + +```bash file=.env +DATABASE_URL="mysql://janedoe:mypassword@server.us-east-2.psdb.cloud/mydb?sslaccept=strict" +``` + +You now need to adjust the connection URL to point to your own database. + +

Connection URL

+ +The [format of the connection URL](/orm/reference/connection-urls) for your database typically depends on the database you use. PlanetScale uses the MySQL connection URL format, which has the following structure (the parts spelled all-uppercased are _placeholders_ for your specific connection details): + +```no-lines +mysql://USER:PASSWORD@HOST:PORT/DATABASE +``` + +Here's a short explanation of each component: + +- `USER`: The name of your database user +- `PASSWORD`: The password for your database user +- `PORT`: The port where your database server is running (typically `3306` for MySQL) +- `DATABASE`: The name of the [database](https://dev.mysql.com/doc/refman/8.0/en/creating-database.html) + +For a database hosted with PlanetScale, the [connection URL](/orm/reference/connection-urls) looks similar to this: + +```bash file=.env +DATABASE_URL="mysql://myusername:mypassword@server.us-east-2.psdb.cloud/mydb?sslaccept=strict" +``` + +The connection URL for a given database branch can be found from your PlanetScale account by going to the overview page for the branch and selecting the 'Connect' dropdown. In the 'Passwords' section, generate a new password and select 'Prisma' to get the Prisma format for the connection URL. + +
+Alternative method: connecting using the PlanetScale CLI + +Alternatively, you can connect to your PlanetScale database server using the [PlanetScale CLI](https://docs.planetscale.com/reference/planetscale-environment-setup), and use a local connection URL. In this case the connection URL will look like this: + +```bash file=.env +DATABASE_URL="mysql://root@localhost:PORT/mydb" +``` + +To connect to your branch, use the following command: + +```terminal +pscale connect prisma-test branchname --port PORT +``` + +The `--port` flag can be omitted if you are using the default port `3306`. + +
+ +
+ + + +```prisma file=prisma/schema.prisma +datasource db { + provider = "sqlserver" + url = env("DATABASE_URL") +} +``` + +The `url` is [set via an environment variable](/orm/prisma-schema/overview#accessing-environment-variables-from-the-schema), the following example connection URL [uses SQL authentication](/orm/overview/databases/sql-server), but there are [other ways to format your connection URL](/orm/overview/databases/sql-server) + +```bash file=.env +DATABASE_URL="sqlserver://localhost:1433;database=mydb;user=sa;password=r@ndomP@$$w0rd;trustServerCertificate=true" +``` + +Adjust the connection URL to match your setup - see [Microsoft SQL Server connection URL](/orm/overview/databases/sql-server) for more information. + +> Make sure TCP/IP connections are enabled via [SQL Server Configuration Manager](https://docs.microsoft.com/en-us/sql/relational-databases/sql-server-configuration-manager) to avoid `No connection could be made because the target machine actively refused it. (os error 10061)` + + + + + +```prisma file=prisma/schema.prisma +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} +``` + +Note that the default schema created by `prisma init` uses PostgreSQL as the `provider`. For CockroachDB, you need to edit the `datasource` block to use the `cockroachdb` provider instead: + +```prisma file=prisma/schema.prisma highlight=2;edit +datasource db { + provider = "cockroachdb" + url = env("DATABASE_URL") +} +``` + +The `url` is [set via an environment variable](/orm/more/development-environment/environment-variables) which is defined in `.env`. You now need to adjust the connection URL to point to your own database. + +

Connection URL

+ +The [format of the connection URL](/orm/reference/connection-urls) for your database depends on the database you use. CockroachDB uses the PostgreSQL connection URL format, which has the following structure (the parts spelled all-uppercased are _placeholders_ for your specific connection details): + +```no-lines +postgresql://USER:PASSWORD@HOST:PORT/DATABASE?PARAMETERS +``` + +Here's a short explanation of each component: + +- `USER`: The name of your database user +- `PASSWORD`: The password for your database user +- `PORT`: The port where your database server is running. The default for CockroachDB is `26257`. +- `DATABASE`: The name of the database +- `PARAMETERS`: Any additional connection parameters. See the CockroachDB documentation [here](https://www.cockroachlabs.com/docs/stable/connection-parameters.html#additional-connection-parameters). + +For a [CockroachDB Serverless](https://www.cockroachlabs.com/docs/cockroachcloud/quickstart.html) or [Cockroach Dedicated](https://www.cockroachlabs.com/docs/cockroachcloud/quickstart-trial-cluster) database hosted on [CockroachDB Cloud](https://www.cockroachlabs.com/get-started-cockroachdb/), the [connection URL](/orm/reference/connection-urls) looks similar to this: + +```bash file=.env +DATABASE_URL="postgresql://:@..cockroachlabs.cloud:26257/defaultdb?sslmode=verify-full&sslrootcert=$HOME/.postgresql/root.crt&options=--" +``` + +To find your connection string on CockroachDB Cloud, click the 'Connect' button on the overview page for your database cluster, and select the 'Connection string' tab. + +For a [CockroachDB database hosted locally](https://www.cockroachlabs.com/docs/stable/secure-a-cluster.html), the [connection URL](/orm/reference/connection-urls) looks similar to this: + +```bash file=.env +DATABASE_URL="postgresql://root@localhost:26257?sslmode=disable" +``` + +Your connection string is displayed as part of the welcome text when starting CockroachDB from the command line. + +
+ + + + + + + Installation + + + + Introspection + + + + + + + + + + + + Installation + + + + Introspection + + + + + + + + + + + + Installation + + + + Introspection + + + + + + + + + + + + Installation + + + + Introspection + + + + + + + + + + + + Installation + + + + Introspection + + + + + + + + + + + + Installation + + + + Introspection + + + + + + + + + + + + Installation + + + + Introspection + + + + + + + + + + + + Installation + + + + Introspection + + + + + + + + + + + + Installation + + + + Introspection + + + + + + + + + + + + Installation + + + + Introspection + + + + + diff --git a/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/150-introspection.mdx b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/150-introspection.mdx new file mode 100644 index 0000000000..074039fae1 --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/150-introspection.mdx @@ -0,0 +1,1329 @@ +--- +title: 'Introspection' +metaTitle: 'Introspection' +metaDescription: 'Introspection your database with Prisma' +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['postgresql', 'mysql', 'sqlserver', 'planetscale', 'cockroachdb'] +toc: false +--- + +## Introspect your database with Prisma + + + +For the purpose of this guide, we'll use a demo SQL schema with three tables: + +```sql no-lines +CREATE TABLE "public"."User" ( + id SERIAL PRIMARY KEY NOT NULL, + name VARCHAR(255), + email VARCHAR(255) UNIQUE NOT NULL +); + +CREATE TABLE "public"."Post" ( + id SERIAL PRIMARY KEY NOT NULL, + title VARCHAR(255) NOT NULL, + "createdAt" TIMESTAMP NOT NULL DEFAULT now(), + content TEXT, + published BOOLEAN NOT NULL DEFAULT false, + "authorId" INTEGER NOT NULL, + FOREIGN KEY ("authorId") REFERENCES "public"."User"(id) +); + +CREATE TABLE "public"."Profile" ( + id SERIAL PRIMARY KEY NOT NULL, + bio TEXT, + "userId" INTEGER UNIQUE NOT NULL, + FOREIGN KEY ("userId") REFERENCES "public"."User"(id) +); +``` + +> **Note**: Some fields are written in double-quotes to ensure PostgreSQL uses proper casing. If no double-quotes were used, PostgreSQL would just read everything as _lowercase_ characters. + +
+Expand for a graphical overview of the tables + +**User** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :------------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `SERIAL` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `name` | `VARCHAR(255)` | No | No | No | - | +| `email` | `VARCHAR(255)` | No | No | **βœ”οΈ** | - | + +**Post** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :------------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `SERIAL` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `createdAt` | `TIMESTAMP` | No | No | **βœ”οΈ** | `now()` | +| `title` | `VARCHAR(255)` | No | No | **βœ”οΈ** | - | +| `content` | `TEXT` | No | No | No | - | +| `published` | `BOOLEAN` | No | No | **βœ”οΈ** | `false` | +| `authorId` | `INTEGER` | No | **βœ”οΈ** | **βœ”οΈ** | - | + +**Profile** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :-------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `SERIAL` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `bio` | `TEXT` | No | No | No | - | +| `userId` | `INTEGER` | No | **βœ”οΈ** | **βœ”οΈ** | - | + +
+ +
+ + + +For the purpose of this guide, we'll use a demo SQL schema with three tables: + +```sql no-lines +CREATE TABLE User ( + id INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL, + name VARCHAR(255), + email VARCHAR(255) UNIQUE NOT NULL +); + +CREATE TABLE Post ( + id INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL, + title VARCHAR(255) NOT NULL, + createdAt TIMESTAMP NOT NULL DEFAULT now(), + content TEXT, + published BOOLEAN NOT NULL DEFAULT false, + authorId INTEGER NOT NULL, + FOREIGN KEY (authorId) REFERENCES User(id) +); + +CREATE TABLE Profile ( + id INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL, + bio TEXT, + userId INTEGER UNIQUE NOT NULL, + FOREIGN KEY (userId) REFERENCES User(id) +); +``` + +
+Expand for a graphical overview of the tables + +**User** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :------------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `INTEGER` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `name` | `VARCHAR(255)` | No | No | No | - | +| `email` | `VARCHAR(255)` | No | No | **βœ”οΈ** | - | + +**Post** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :------------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `INTEGER` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `createdAt` | `DATETIME(3)` | No | No | **βœ”οΈ** | `now()` | +| `title` | `VARCHAR(255)` | No | No | **βœ”οΈ** | - | +| `content` | `TEXT` | No | No | No | - | +| `published` | `BOOLEAN` | No | No | **βœ”οΈ** | `false` | +| `authorId` | `INTEGER` | No | **βœ”οΈ** | **βœ”οΈ** | `false` | + +**Profile** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :-------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `INTEGER` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `bio` | `TEXT` | No | No | No | - | +| `userId` | `INTEGER` | No | **βœ”οΈ** | **βœ”οΈ** | - | + +
+ +
+ + + +For the purpose of this guide, we'll use a demo SQL schema with three tables: + +```sql no-lines +CREATE TABLE `Post` ( + `id` int NOT NULL AUTO_INCREMENT, + `createdAt` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + `updatedAt` datetime(3) NOT NULL, + `title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `content` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `published` tinyint(1) NOT NULL DEFAULT '0', + `authorId` int NOT NULL, + PRIMARY KEY (`id`), + KEY `Post_authorId_idx` (`authorId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE `Profile` ( + `id` int NOT NULL AUTO_INCREMENT, + `bio` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `userId` int NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `Profile_userId_key` (`userId`), + KEY `Profile_userId_idx` (`userId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE `User` ( + `id` int NOT NULL AUTO_INCREMENT, + `email` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, + `name` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `User_email_key` (`email`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +``` + +
+Expand for a graphical overview of the tables + +**Post** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :------------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `int` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `createdAt` | `datetime(3)` | No | No | **βœ”οΈ** | `now()` | +| `updatedAt` | `datetime(3)` | No | No | **βœ”οΈ** | | +| `title` | `varchar(255)` | No | No | **βœ”οΈ** | - | +| `content` | `varchar(191)` | No | No | No | - | +| `published` | `tinyint(1)` | No | No | **βœ”οΈ** | `false` | +| `authorId` | `int` | No | No | **βœ”οΈ** | - | + +**Profile** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :------------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `int` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `bio` | `varchar(191)` | No | No | No | - | +| `userId` | `int` | No | No | **βœ”οΈ** | - | + +**User** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :------------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `int` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `name` | `varchar(191)` | No | No | No | - | +| `email` | `varchar(191)` | No | No | **βœ”οΈ** | - | + +
+ +
+ + + +For the purpose of this guide, we'll use a demo SQL schema with three tables: + +```sql no-lines +CREATE TABLE [dbo].[Post] ( + [id] INT NOT NULL IDENTITY(1,1), + [createdAt] DATETIME2 NOT NULL CONSTRAINT [Post_createdAt_df] DEFAULT CURRENT_TIMESTAMP, + [updatedAt] DATETIME2 NOT NULL, + [title] VARCHAR(255) NOT NULL, + [content] NVARCHAR(1000), + [published] BIT NOT NULL CONSTRAINT [Post_published_df] DEFAULT 0, + [authorId] INT NOT NULL, + CONSTRAINT [Post_pkey] PRIMARY KEY ([id]) +); + +CREATE TABLE [dbo].[Profile] ( + [id] INT NOT NULL IDENTITY(1,1), + [bio] NVARCHAR(1000), + [userId] INT NOT NULL, + CONSTRAINT [Profile_pkey] PRIMARY KEY ([id]), + CONSTRAINT [Profile_userId_key] UNIQUE ([userId]) +); + +CREATE TABLE [dbo].[User] ( + [id] INT NOT NULL IDENTITY(1,1), + [email] NVARCHAR(1000) NOT NULL, + [name] NVARCHAR(1000), + CONSTRAINT [User_pkey] PRIMARY KEY ([id]), + CONSTRAINT [User_email_key] UNIQUE ([email]) +); + +ALTER TABLE [dbo].[Post] ADD CONSTRAINT [Post_authorId_fkey] FOREIGN KEY ([authorId]) REFERENCES [dbo].[User]([id]) ON DELETE NO ACTION ON UPDATE CASCADE; + +ALTER TABLE [dbo].[Profile] ADD CONSTRAINT [Profile_userId_fkey] FOREIGN KEY ([userId]) REFERENCES [dbo].[User]([id]) ON DELETE NO ACTION ON UPDATE CASCADE; +``` + +
+Expand for a graphical overview of the tables + +**User** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :--------------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `INT` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `name` | `NVARCHAR(1000)` | No | No | No | - | +| `email` | `NVARCHAR(1000)` | No | No | **βœ”οΈ** | - | + +**Post** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :--------------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `INT` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `createdAt` | `DATETIME2` | No | No | **βœ”οΈ** | `now()` | +| `updatedAt` | `DATETIME2` | No | No | **βœ”οΈ** | | +| `title` | `VARCHAR(255)` | No | No | **βœ”οΈ** | - | +| `content` | `NVARCHAR(1000)` | No | No | No | - | +| `published` | `BIT` | No | No | **βœ”οΈ** | `false` | +| `authorId` | `INT` | No | **βœ”οΈ** | **βœ”οΈ** | - | + +**Profile** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :--------------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `INT` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `bio` | `NVARCHAR(1000)` | No | No | No | - | +| `userId` | `INT` | No | **βœ”οΈ** | **βœ”οΈ** | - | + +
+ +
+ + + +For the purpose of this guide, we'll use a demo SQL schema with three tables: + +```sql no-lines +CREATE TABLE "User" ( + id INT8 PRIMARY KEY DEFAULT unique_rowid(), + name STRING(255), + email STRING(255) UNIQUE NOT NULL +); + +CREATE TABLE "Post" ( + id INT8 PRIMARY KEY DEFAULT unique_rowid(), + title STRING(255) UNIQUE NOT NULL, + "createdAt" TIMESTAMP NOT NULL DEFAULT now(), + content STRING, + published BOOLEAN NOT NULL DEFAULT false, + "authorId" INT8 NOT NULL, + FOREIGN KEY ("authorId") REFERENCES "User"(id) +); + +CREATE TABLE "Profile" ( + id INT8 PRIMARY KEY DEFAULT unique_rowid(), + bio STRING, + "userId" INT8 UNIQUE NOT NULL, + FOREIGN KEY ("userId") REFERENCES "User"(id) +); +``` + +> **Note**: Some fields are written in double quotes to ensure CockroachDB uses proper casing. If no double-quotes were used, CockroachDB would just read everything as _lowercase_ characters. + +
+Expand for a graphical overview of the tables + +**User** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :------------ | :---------- | :---------- | :------- | :----------------- | +| `id` | `INT8` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `name` | `STRING(255)` | No | No | No | - | +| `email` | `STRING(255)` | No | No | **βœ”οΈ** | - | + +**Post** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :------------ | :---------- | :---------- | :------- | :----------------- | +| `id` | `INT8` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `createdAt` | `TIMESTAMP` | No | No | **βœ”οΈ** | `now()` | +| `title` | `STRING(255)` | No | No | **βœ”οΈ** | - | +| `content` | `STRING` | No | No | No | - | +| `published` | `BOOLEAN` | No | No | **βœ”οΈ** | `false` | +| `authorId` | `INT8` | No | **βœ”οΈ** | **βœ”οΈ** | - | + +**Profile** + +| Column name | Type | Primary key | Foreign key | Required | Default | +| :---------- | :------- | :---------- | :---------- | :------- | :----------------- | +| `id` | `INT8` | **βœ”οΈ** | No | **βœ”οΈ** | _autoincrementing_ | +| `bio` | `STRING` | No | No | No | - | +| `userId` | `INT8` | No | **βœ”οΈ** | **βœ”οΈ** | - | + +
+ +
+ + + +As a next step, you will introspect your database. The result of the introspection will be a [data model](/orm/prisma-schema/data-model/models) inside your Prisma schema. + +Run the following command to introspect your database: + +```terminal copy +npx prisma db pull +``` + +This commands reads the `DATABASE_URL` environment variable that's defined in `.env` and connects to your database. Once the connection is established, it introspects the database (i.e. it _reads the database schema_). It then translates the database schema from SQL into a Prisma data model. + +After the introspection is complete, your Prisma schema file was updated: + +![Introspect your database with Prisma](/img/getting-started/prisma-db-pull-generate-schema.png) + +The data model now looks similar to this (note that the fields on the models have been reordered for better readability): + +```prisma file=prisma/schema.prisma +model Post { + id Int @id @default(autoincrement()) + title String @db.VarChar(255) + createdAt DateTime @default(now()) @db.Timestamp(6) + content String? + published Boolean @default(false) + authorId Int + User User @relation(fields: [authorId], references: [id], onDelete: NoAction, onUpdate: NoAction) +} + +model Profile { + id Int @id @default(autoincrement()) + bio String? + userId Int @unique + User User @relation(fields: [userId], references: [id], onDelete: NoAction, onUpdate: NoAction) +} + +model User { + id Int @id @default(autoincrement()) + name String? @db.VarChar(255) + email String @unique @db.VarChar(255) + Post Post[] + Profile Profile? +} +``` + +Prisma's data model is a declarative representation of your database schema and serves as the foundation for the generated Prisma Client library. Your Prisma Client instance will expose queries that are _tailored_ to these models. + +Right now, there's a few minor "issues" with the data model: + +- The `User` relation field is uppercased and therefore doesn't adhere to Prisma's [naming conventions](/orm/reference/prisma-schema-reference#naming-conventions-1) . To express more "semantics", it would also be nice if this field was called `author` to _describe_ the relationship between `User` and `Post` better. +- The `Post` and `Profile` relation fields on `User` as well as the `User` relation field on `Profile` are all uppercased. To adhere to Prisma's [naming conventions](/orm/reference/prisma-schema-reference#naming-conventions-1) , both fields should be lowercased to `post`, `profile` and `user`. +- Even after lowercasing, the `post` field on `User` is still slightly misnamed. That's because it actually refers to a [list](/orm/prisma-schema/data-model/models#type-modifiers) of posts – a better name therefore would be the plural form: `posts`. + +These changes are relevant for the generated Prisma Client API where using lowercased relation fields `author`, `posts`, `profile` and `user` will feel more natural and idiomatic to JavaScript/TypeScript developers. You can therefore [configure your Prisma Client API](/orm/prisma-client/setup-and-configuration/custom-model-and-field-names). + +Because [relation fields](/orm/prisma-schema/data-model/relations#relation-fields) are _virtual_ (i.e. they _do not directly manifest in the database_), you can manually rename them in your Prisma schema without touching the database: + +```prisma file=prisma/schema.prisma highlight=8,15,22,23;edit +model Post { + id Int @id @default(autoincrement()) + title String @db.VarChar(255) + createdAt DateTime @default(now()) @db.Timestamp(6) + content String? + published Boolean @default(false) + authorId Int + author User @relation(fields: [authorId], references: [id], onDelete: NoAction, onUpdate: NoAction) +} + +model Profile { + id Int @id @default(autoincrement()) + bio String? + userId Int @unique + user User @relation(fields: [userId], references: [id], onDelete: NoAction, onUpdate: NoAction) +} + +model User { + id Int @id @default(autoincrement()) + name String? @db.VarChar(255) + email String @unique @db.VarChar(255) + posts Post[] + profile Profile? +} +``` + +In this example, the database schema did follow the [naming conventions](/orm/reference/prisma-schema-reference#naming-conventions) for Prisma models (only the virtual relation fields that were generated from introspection did not adhere to them and needed adjustment). This optimizes the ergonomics of the generated Prisma Client API. + +
+ Using custom model and field names + +Sometimes though, you may want to make additional changes to the names of the columns and tables that are exposed in the Prisma Client API. A common example is to translate _snake_case_ notation which is often used in database schemas into _PascalCase_ and _camelCase_ notations which feel more natural for JavaScript/TypeScript developers. + +Assume you obtained the following model from introspection that's based on _snake_case_ notation: + +```prisma no-lines +model my_user { + user_id Int @id @default(autoincrement()) + first_name String? + last_name String @unique +} +``` + +If you generated a Prisma Client API for this model, it would pick up the _snake_case_ notation in its API: + +```ts no-lines +const user = await prisma.my_user.create({ + data: { + first_name: 'Alice', + last_name: 'Smith', + }, +}) +``` + +If you don't want to use the table and column names from your database in your Prisma Client API, you can configure them with [`@map` and `@@map`](/orm/prisma-schema/data-model/models#mapping-model-names-to-tables-or-collections): + +```prisma no-lines +model MyUser { + userId Int @id @default(autoincrement()) @map("user_id") + firstName String? @map("first_name") + lastName String @unique @map("last_name") + + @@map("my_user") +} +``` + +With this approach, you can name your model and its fields whatever you like and use the `@map` (for field names) and `@@map` (for models names) to point to the underlying tables and columns. Your Prisma Client API now looks as follows: + +```ts no-lines +const user = await prisma.myUser.create({ + data: { + firstName: 'Alice', + lastName: 'Smith', + }, +}) +``` + +Learn more about this on the [Configuring your Prisma Client API](/orm/prisma-client/setup-and-configuration/custom-model-and-field-names) page. + +
+ +
+ + + +As a next step, you will introspect your database. The result of the introspection will be a [data model](/orm/prisma-schema/data-model/models) inside your Prisma schema. + +Run the following command to introspect your database: + +```terminal copy +npx prisma db pull +``` + +This commands reads the `DATABASE_URL` environment variable that's defined in `.env` and connects to your database. Once the connection is established, it introspects the database (i.e. it _reads the database schema_). It then translates the database schema from SQL into a Prisma data model. + +After the introspection is complete, your Prisma schema file was updated: + +![Introspect your database with Prisma](/img/getting-started/prisma-db-pull-generate-schema.png) + +The data model now looks similar to this (note that the fields on the models have been reordered for better readability): + +```prisma file=prisma/schema.prisma +model Post { + id Int @id @default(autoincrement()) + title String @db.VarChar(255) + createdAt DateTime @default(now()) @db.Timestamp(0) + content String? @db.Text + published Boolean @default(false) + authorId Int + User User @relation(fields: [authorId], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "Post_ibfk_1") + + @@index([authorId], map: "authorId") +} + +model Profile { + id Int @id @default(autoincrement()) + bio String? @db.Text + userId Int @unique(map: "userId") + User User @relation(fields: [userId], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "Profile_ibfk_1") +} + +model User { + id Int @id @default(autoincrement()) + name String? @db.VarChar(255) + email String @unique(map: "email") @db.VarChar(255) + Post Post[] + Profile Profile? +} +``` + + + +Refer to the [Prisma schema reference](/orm/reference/prisma-schema-reference) for detailed information about the schema definition. + + + +Prisma's data model is a declarative representation of your database schema and serves as the foundation for the generated Prisma Client library. Your Prisma Client instance will expose queries that are _tailored_ to these models. + +Right now, there's a few minor "issues" with the data model: + +- The `User` relation field is uppercased and therefore doesn't adhere to Prisma's [naming conventions](/orm/reference/prisma-schema-reference#naming-conventions-1) . To express more "semantics", it would also be nice if this field was called `author` to _describe_ the relationship between `User` and `Post` better. +- The `Post` and `Profile` relation fields on `User` as well as the `User` relation field on `Profile` are all uppercased. To adhere to Prisma's [naming conventions](/orm/reference/prisma-schema-reference#naming-conventions-1) , both fields should be lowercased to `post`, `profile` and `user`. +- Even after lowercasing, the `post` field on `User` is still slightly misnamed. That's because it actually refers to a [list](/orm/prisma-schema/data-model/models#type-modifiers) of posts – a better name therefore would be the plural form: `posts`. + +These changes are relevant for the generated Prisma Client API where using lowercased relation fields `author`, `posts`, `profile` and `user` will feel more natural and idiomatic to JavaScript/TypeScript developers. You can therefore [configure your Prisma Client API](/orm/prisma-client/setup-and-configuration/custom-model-and-field-names). + +Because [relation fields](/orm/prisma-schema/data-model/relations#relation-fields) are _virtual_ (i.e. they _do not directly manifest in the database_), you can manually rename them in your Prisma schema without touching the database: + +```prisma file=prisma/schema.prisma highlight=8,17,24,25;edit +model Post { + id Int @id @default(autoincrement()) + title String @db.VarChar(255) + createdAt DateTime @default(now()) @db.Timestamp(0) + content String? @db.Text + published Boolean @default(false) + authorId Int + author User @relation(fields: [authorId], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "Post_ibfk_1") + + @@index([authorId], map: "authorId") +} + +model Profile { + id Int @id @default(autoincrement()) + bio String? @db.Text + userId Int @unique(map: "userId") + user User @relation(fields: [userId], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "Profile_ibfk_1") +} + +model User { + id Int @id @default(autoincrement()) + name String? @db.VarChar(255) + email String @unique(map: "email") @db.VarChar(255) + posts Post[] + profile Profile? +} +``` + +In this example, the database schema did follow the [naming conventions](/orm/reference/prisma-schema-reference#naming-conventions) for Prisma models (only the virtual relation fields that were generated from introspection did not adhere to them and needed adjustment). This optimizes the ergonomics of the generated Prisma Client API. + +Sometimes though, you may want to make additional changes to the names of the columns and tables that are exposed in the Prisma Client API. A common example is to translate _snake_case_ notation which is often used in database schemas into _PascalCase_ and _camelCase_ notations which feel more natural for JavaScript/TypeScript developers. + +Assume you obtained the following model from introspection that's based on _snake_case_ notation: + +```prisma no-lines +model my_user { + user_id Int @id @default(autoincrement()) + first_name String? + last_name String @unique +} +``` + +If you generated a Prisma Client API for this model, it would pick up the _snake_case_ notation in its API: + +```ts no-lines +const user = await prisma.my_user.create({ + data: { + first_name: 'Alice', + last_name: 'Smith', + }, +}) +``` + +If you don't want to use the table and column names from your database in your Prisma Client API, you can configure them with [`@map` and `@@map`](/orm/prisma-schema/data-model/models#mapping-model-names-to-tables-or-collections): + +```prisma no-lines +model MyUser { + userId Int @id @default(autoincrement()) @map("user_id") + firstName String? @map("first_name") + lastName String @unique @map("last_name") + + @@map("my_user") +} +``` + +With this approach, you can name your model and its fields whatever you like and use the `@map` (for field names) and `@@map` (for models names) to point to the underlying tables and columns. Your Prisma Client API now looks as follows: + +```ts no-lines +const user = await prisma.myUser.create({ + data: { + firstName: 'Alice', + lastName: 'Smith', + }, +}) +``` + +Learn more about this on the [Configuring your Prisma Client API](/orm/prisma-client/setup-and-configuration/custom-model-and-field-names) page. + + + + + +As a next step, you will introspect your database. The result of the introspection will be a [data model](/orm/prisma-schema/data-model/models) inside your Prisma schema. + +Run the following command to introspect your database: + +```terminal copy +npx prisma db pull +``` + +This commands reads the `DATABASE_URL` environment variable that's defined in `.env` and connects to your database. Once the connection is established, it introspects the database (i.e. it _reads the database schema_). It then translates the database schema from SQL into a Prisma data model. + +After the introspection is complete, your Prisma schema file was updated: + +![Introspect your database with Prisma](/img/getting-started/prisma-db-pull-generate-schema.png) + +The data model now looks similar to this (note that the fields on the models have been reordered for better readability): + +```prisma file=prisma/schema.prisma +model Post { + id Int @id @default(autoincrement()) + title String @db.VarChar(255) + createdAt DateTime @default(now()) @db.Timestamp(6) + content String? + published Boolean @default(false) + authorId Int + User User @relation(fields: [authorId], references: [id]) +} + +model Profile { + id Int @id @default(autoincrement()) + bio String? + userId Int @unique + User User @relation(fields: [userId], references: [id]) +} + +model User { + id Int @id @default(autoincrement()) + name String? @db.VarChar(255) + email String @unique @db.VarChar(255) + Post Post[] + Profile Profile? +} +``` + +Prisma's data model is a declarative representation of your database schema and serves as the foundation for the generated Prisma Client library. Your Prisma Client instance will expose queries that are _tailored_ to these models. + +Right now, there's a few minor "issues" with the data model: + +- The `User` relation field is uppercased and therefore doesn't adhere to Prisma's [naming conventions](/orm/reference/prisma-schema-reference#naming-conventions-1) . To express more "semantics", it would also be nice if this field was called `author` to _describe_ the relationship between `User` and `Post` better. +- The `Post` and `Profile` relation fields on `User` as well as the `User` relation field on `Profile` are all uppercased. To adhere to Prisma's [naming conventions](/orm/reference/prisma-schema-reference#naming-conventions-1) , both fields should be lowercased to `post`, `profile` and `user`. +- Even after lowercasing, the `post` field on `User` is still slightly misnamed. That's because it actually refers to a [list](/orm/prisma-schema/data-model/models#type-modifiers) of posts – a better name therefore would be the plural form: `posts`. + +These changes are relevant for the generated Prisma Client API where using lowercased relation fields `author`, `posts`, `profile` and `user` will feel more natural and idiomatic to JavaScript/TypeScript developers. You can therefore [configure your Prisma Client API](/orm/prisma-client/setup-and-configuration/custom-model-and-field-names). + +Because [relation fields](/orm/prisma-schema/data-model/relations#relation-fields) are _virtual_ (i.e. they _do not directly manifest in the database_), you can manually rename them in your Prisma schema without touching the database: + +```prisma file=prisma/schema.prisma highlight=7,14,22,23;edit +model Post { + id Int @id @default(autoincrement()) + title String @db.VarChar(255) + createdAt DateTime @default(now()) @db.Timestamp(6) + content String? + published Boolean @default(false) + author User @relation(fields: [authorId], references: [id]) + authorId Int +} + +model Profile { + id Int @id @default(autoincrement()) + bio String? + user User @relation(fields: [userId], references: [id]) + userId Int @unique +} + +model User { + id Int @id @default(autoincrement()) + email String @unique @db.VarChar(255) + name String? @db.VarChar(255) + posts Post[] + profile Profile? +} +``` + +In this example, the database schema did follow the [naming conventions](/orm/reference/prisma-schema-reference#naming-conventions) for Prisma models (only the virtual relation fields that were generated from introspection did not adhere to them and needed adjustment). This optimizes the ergonomics of the generated Prisma Client API. + +
+ Using custom model and field names + +Sometimes though, you may want to make additional changes to the names of the columns and tables that are exposed in the Prisma Client API. A common example is to translate _snake_case_ notation which is often used in database schemas into _PascalCase_ and _camelCase_ notations which feel more natural for JavaScript/TypeScript developers. + +Assume you obtained the following model from introspection that's based on _snake_case_ notation: + +```prisma no-lines +model my_user { + user_id Int @id @default(autoincrement()) + first_name String? + last_name String @unique +} +``` + +If you generated a Prisma Client API for this model, it would pick up the _snake_case_ notation in its API: + +```ts no-lines +const user = await prisma.my_user.create({ + data: { + first_name: 'Alice', + last_name: 'Smith', + }, +}) +``` + +If you don't want to use the table and column names from your database in your Prisma Client API, you can configure them with [`@map` and `@@map`](/orm/prisma-schema/data-model/models#mapping-model-names-to-tables-or-collections): + +```prisma no-lines +model MyUser { + userId Int @id @default(autoincrement()) @map("user_id") + firstName String? @map("first_name") + lastName String @unique @map("last_name") + + @@map("my_user") +} +``` + +With this approach, you can name your model and its fields whatever you like and use the `@map` (for field names) and `@@map` (for models names) to point to the underlying tables and columns. Your Prisma Client API now looks as follows: + +```ts no-lines +const user = await prisma.myUser.create({ + data: { + firstName: 'Alice', + lastName: 'Smith', + }, +}) +``` + +Learn more about this on the [Configuring your Prisma Client API](/orm/prisma-client/setup-and-configuration/custom-model-and-field-names) page. + +
+ +
+ + + +As a next step, you will introspect your database. The result of the introspection will be a [data model](/orm/prisma-schema/data-model/models) inside your Prisma schema. + +Run the following command to introspect your database: + +```terminal copy +npx prisma db pull +``` + +This commands reads the `DATABASE_URL` environment variable that's defined in `.env` and connects to your database. Once the connection is established, it introspects the database (i.e. it _reads the database schema_). It then translates the database schema from SQL into a Prisma data model. + +After the introspection is complete, your Prisma schema file was updated: + +![Introspect your database with Prisma](/img/getting-started/prisma-db-pull-generate-schema.png) + +The data model now looks similar to this: + +```prisma file=prisma/schema.prisma +model Post { + id Int @id @default(autoincrement()) + createdAt DateTime @default(now()) + updatedAt DateTime + title String @db.VarChar(255) + content String? + published Boolean @default(false) + authorId Int + + @@index([authorId]) +} + +model Profile { + id Int @id @default(autoincrement()) + bio String? + userId Int @unique + + @@index([userId]) +} + +model User { + id Int @id @default(autoincrement()) + email String @unique + name String? +} +``` + + + +Refer to the [Prisma schema reference](/orm/reference/prisma-schema-reference) for detailed information about the schema definition. + + + +Prisma's data model is a declarative representation of your database schema and serves as the foundation for the generated Prisma Client library. Your Prisma Client instance will expose queries that are _tailored_ to these models. + +You will then need to add in any missing relations between your data using [relation fields](/orm/prisma-schema/data-model/relations#relation-fields): + +```prisma file=prisma/schema.prisma highlight=8,17,27,28;add +model Post { + id Int @id @default(autoincrement()) + createdAt DateTime @default(now()) + updatedAt DateTime + title String @db.VarChar(255) + content String? + published Boolean @default(false) + author User @relation(fields: [authorId], references: [id]) + authorId Int + + @@index([authorId]) +} + +model Profile { + id Int @id @default(autoincrement()) + bio String? + user User @relation(fields: [userId], references: [id]) + userId Int @unique + + @@index([userId]) +} + +model User { + id Int @id @default(autoincrement()) + email String @unique + name String? + posts Post[] + profile Profile? +} +``` + +After this, run introspection on your database for a second time: + +```terminal copy +npx prisma db pull +``` + +Prisma Migrate will now keep the manually added relation fields. + +Because relation fields are _virtual_ (i.e. they _do not directly manifest in the database_), you can manually rename them in your Prisma schema without touching the database. + +In this example, the database schema follows the [naming conventions](/orm/reference/prisma-schema-reference#naming-conventions) for Prisma models. This optimizes the ergonomics of the generated Prisma Client API. + +
+ Using custom model and field names + +Sometimes though, you may want to make additional changes to the names of the columns and tables that are exposed in the Prisma Client API. A common example is to translate _snake_case_ notation which is often used in database schemas into _PascalCase_ and _camelCase_ notations which feel more natural for JavaScript/TypeScript developers. + +Assume you obtained the following model from introspection that's based on _snake_case_ notation: + +```prisma no-lines +model my_user { + user_id Int @id @default(autoincrement()) + first_name String? + last_name String @unique +} +``` + +If you generated a Prisma Client API for this model, it would pick up the _snake_case_ notation in its API: + +```ts no-lines +const user = await prisma.my_user.create({ + data: { + first_name: 'Alice', + last_name: 'Smith', + }, +}) +``` + +If you don't want to use the table and column names from your database in your Prisma Client API, you can configure them with [`@map` and `@@map`](/orm/prisma-schema/data-model/models#mapping-model-names-to-tables-or-collections): + +```prisma no-lines +model MyUser { + userId Int @id @default(autoincrement()) @map("user_id") + firstName String? @map("first_name") + lastName String @unique @map("last_name") + + @@map("my_user") +} +``` + +With this approach, you can name your model and its fields whatever you like and use the `@map` (for field names) and `@@map` (for models names) to point to the underlying tables and columns. Your Prisma Client API now looks as follows: + +```ts no-lines +const user = await prisma.myUser.create({ + data: { + firstName: 'Alice', + lastName: 'Smith', + }, +}) +``` + +Learn more about this on the [Configuring your Prisma Client API](/orm/prisma-client/setup-and-configuration/custom-model-and-field-names) page. + +
+ +
+ + + +As a next step, you will introspect your database. The result of the introspection will be a [data model](/orm/prisma-schema/data-model/models) inside your Prisma schema. + +Run the following command to introspect your database: + +```terminal copy +npx prisma db pull +``` + +This commands reads the environment variable used to define the `url` in your `schema.prisma`, `DATABASE_URL`, that in our case is set in `.env` and connects to your database. Once the connection is established, it introspects the database (i.e. it _reads the database schema_). It then translates the database schema from SQL into a Prisma data model. + +After the introspection is complete, your Prisma schema file was updated: + +![Introspect your database with Prisma](/img/getting-started/prisma-db-pull-generate-schema.png) + +The data model now looks similar to this: + +```prisma file=prisma/schema.prisma +model Post { + id BigInt @id @default(autoincrement()) + title String @unique @db.String(255) + createdAt DateTime @default(now()) @db.Timestamp(6) + content String? + published Boolean @default(false) + authorId BigInt + User User @relation(fields: [authorId], references: [id], onDelete: NoAction, onUpdate: NoAction) +} + +model Profile { + id BigInt @id @default(autoincrement()) + bio String? + userId BigInt @unique + User User @relation(fields: [userId], references: [id], onDelete: NoAction, onUpdate: NoAction) +} + +model User { + id BigInt @id @default(autoincrement()) + name String? @db.String(255) + email String @unique @db.String(255) + Post Post[] + Profile Profile? +} +``` + +Prisma's data model is a declarative representation of your database schema and serves as the foundation for the generated Prisma Client library. Your Prisma Client instance will expose queries that are _tailored_ to these models. + +Right now, there's a few minor "issues" with the data model: + +- The `User` relation field is uppercased and therefore doesn't adhere to Prisma's [naming conventions](/orm/reference/prisma-schema-reference#naming-conventions-1) . To express more "semantics", it would also be nice if this field was called `author` to _describe_ the relationship between `User` and `Post` better. +- The `Post` and `Profile` relation fields on `User` as well as the `User` relation field on `Profile` are all uppercased. To adhere to Prisma's [naming conventions](/orm/reference/prisma-schema-reference#naming-conventions-1) , both fields should be lowercased to `post`, `profile` and `user`. +- Even after lowercasing, the `post` field on `User` is still slightly misnamed. That's because it actually refers to a [list](/orm/prisma-schema/data-model/models#type-modifiers) of posts – a better name therefore would be the plural form: `posts`. + +These changes are relevant for the generated Prisma Client API where using lowercased relation fields `author`, `posts`, `profile` and `user` will feel more natural and idiomatic to JavaScript/TypeScript developers. You can therefore [configure your Prisma Client API](/orm/prisma-client/setup-and-configuration/custom-model-and-field-names). + +Because [relation fields](/orm/prisma-schema/data-model/relations#relation-fields) are _virtual_ (i.e. they _do not directly manifest in the database_), you can manually rename them in your Prisma schema without touching the database: + +```prisma file=prisma/schema.prisma highlight=8,15,22,23;edit +model Post { + id BigInt @id @default(autoincrement()) + title String @unique @db.String(255) + createdAt DateTime @default(now()) @db.Timestamp(6) + content String? + published Boolean @default(false) + authorId BigInt + author User @relation(fields: [authorId], references: [id], onDelete: NoAction, onUpdate: NoAction) +} + +model Profile { + id BigInt @id @default(autoincrement()) + bio String? + userId BigInt @unique + user User @relation(fields: [userId], references: [id], onDelete: NoAction, onUpdate: NoAction) +} + +model User { + id BigInt @id @default(autoincrement()) + name String? @db.String(255) + email String @unique @db.String(255) + posts Post[] + profile Profile? +} +``` + +In this example, the database schema did follow the [naming conventions](/orm/reference/prisma-schema-reference#naming-conventions) for Prisma models (only the virtual relation fields that were generated from introspection did not adhere to them and needed adjustment). This optimizes the ergonomics of the generated Prisma Client API. + +
+ Using custom model and field names + +Sometimes though, you may want to make additional changes to the names of the columns and tables that are exposed in the Prisma Client API. A common example is to translate _snake_case_ notation which is often used in database schemas into _PascalCase_ and _camelCase_ notations which feel more natural for JavaScript/TypeScript developers. + +Assume you obtained the following model from introspection that's based on _snake_case_ notation: + +```prisma no-lines +model my_user { + user_id Int @id @default(sequence()) + first_name String? + last_name String @unique +} +``` + +If you generated a Prisma Client API for this model, it would pick up the _snake_case_ notation in its API: + +```ts no-lines +const user = await prisma.my_user.create({ + data: { + first_name: 'Alice', + last_name: 'Smith', + }, +}) +``` + +If you don't want to use the table and column names from your database in your Prisma Client API, you can configure them with [`@map` and `@@map`](/orm/prisma-schema/data-model/models#mapping-model-names-to-tables-or-collections): + +```prisma no-lines +model MyUser { + userId Int @id @default(sequence()) @map("user_id") + firstName String? @map("first_name") + lastName String @unique @map("last_name") + + @@map("my_user") +} +``` + +With this approach, you can name your model and its fields whatever you like and use the `@map` (for field names) and `@@map` (for models names) to point to the underlying tables and columns. Your Prisma Client API now looks as follows: + +```ts no-lines +const user = await prisma.myUser.create({ + data: { + firstName: 'Alice', + lastName: 'Smith', + }, +}) +``` + +Learn more about this on the [Configuring your Prisma Client API](/orm/prisma-client/setup-and-configuration/custom-model-and-field-names) page. + +
+ +
+ + + + + + + Connect your database + + + + Baseline your database + + + + + + + + + + + + Connect your database + + + + Baseline your database + + + + + + + + + + + + Connect your database + + + + Install Prisma Client + + + + + + + + + + + + Connect your database + + + + Baseline your database + + + + + + + + + + + + Connect your database + + + + Baseline your database + + + + + + + + + + + + Connect your database + + + + Baseline your database + + + + + + + + + + + + Connect your database + + + + Baseline your database + + + + + + + + + + + + Connect your database + + + + Install Prisma Client + + + + + + + + + + + + Connect your database + + + + Baseline your database + + + + + + + + + + + + Connect your database + + + + Baseline your database + + + + + diff --git a/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/170-baseline-your-database.mdx b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/170-baseline-your-database.mdx new file mode 100644 index 0000000000..88f71c91ac --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/170-baseline-your-database.mdx @@ -0,0 +1,421 @@ +--- +title: 'Baseline your database' +metaTitle: 'Baseline your database' +metaDescription: 'Baseline your database using Prisma Migrate in your project' +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['postgresql', 'mysql', 'sqlserver', 'cockroachdb'] +toc: false +--- + +## Create an initial migration + +To use Prisma Migrate with the database you introspected in the last section, you will need to [baseline your database](/orm/prisma-migrate/getting-started). + +Baselining refers to initializing your migration history for a database that might already contain data and **cannot be reset**, such as your production database. Baselining tells Prisma Migrate to assume that one or more migrations have already been applied to your database. + +To baseline your database, use [`prisma migrate diff`](/orm/reference/prisma-cli-reference#migrate-diff) to compare your schema and database, and save the output into a SQL file. + +First, create a `migrations` directory and add a directory inside with your preferred name for the migration. In this example, we will use `0_init` as the migration name: + +```terminal +mkdir -p prisma/migrations/0_init +``` + + + +`-p` will recursively create any missing folders in the path you provide. + + + +Next, generate the migration file with `prisma migrate diff`. Use the following arguments: + +- `--from-empty`: assumes the data model you're migrating from is empty +- `--to-schema-datamodel`: the current database state using the URL in the `datasource` block +- `--script`: output a SQL script + +```terminal wrap +npx prisma migrate diff --from-empty --to-schema-datamodel prisma/schema.prisma --script > prisma/migrations/0_init/migration.sql +``` + +## Review the migration + +The command will generate a migration that should resemble the following script: + + + +```sql file=prisma/migrations/0_init/migration.sql +-- CreateTable +CREATE TABLE "Post" ( + "id" SERIAL NOT NULL, + "title" VARCHAR(255) NOT NULL, + "createdAt" TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "content" TEXT, + "published" BOOLEAN NOT NULL DEFAULT false, + "authorId" INTEGER NOT NULL, + + CONSTRAINT "Post_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Profile" ( + "id" SERIAL NOT NULL, + "bio" TEXT, + "userId" INTEGER NOT NULL, + + CONSTRAINT "Profile_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "User" ( + "id" SERIAL NOT NULL, + "name" VARCHAR(255), + "email" VARCHAR(255) NOT NULL, + + CONSTRAINT "User_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "Profile_userId_key" ON "Profile"("userId"); + +-- CreateIndex +CREATE UNIQUE INDEX "User_email_key" ON "User"("email"); + +-- AddForeignKey +ALTER TABLE "Post" ADD CONSTRAINT "Post_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +-- AddForeignKey +ALTER TABLE "Profile" ADD CONSTRAINT "Profile_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE NO ACTION ON UPDATE NO ACTION; +``` + + + + + +```sql file=prisma/migrations/0_init/migration.sql +-- CreateTable +CREATE TABLE `Post` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `title` VARCHAR(255) NOT NULL, + `createdAt` TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0), + `content` TEXT NULL, + `published` BOOLEAN NOT NULL DEFAULT false, + `authorId` INTEGER NOT NULL, + + INDEX `authorId`(`authorId`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `Profile` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `bio` TEXT NULL, + `userId` INTEGER NOT NULL, + + UNIQUE INDEX `userId`(`userId`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `User` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `name` VARCHAR(255) NULL, + `email` VARCHAR(255) NOT NULL, + + UNIQUE INDEX `email`(`email`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- AddForeignKey +ALTER TABLE `Post` ADD CONSTRAINT `Post_ibfk_1` FOREIGN KEY (`authorId`) REFERENCES `User`(`id`) ON DELETE RESTRICT ON UPDATE RESTRICT; + +-- AddForeignKey +ALTER TABLE `Profile` ADD CONSTRAINT `Profile_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE RESTRICT ON UPDATE RESTRICT; +``` + + + + + +```sql file=prisma/migrations/0_init/migration.sql +CREATE TABLE [dbo].[Post] ( + [id] INT NOT NULL IDENTITY(1,1), + [createdAt] DATETIME2 NOT NULL CONSTRAINT [Post_createdAt_df] DEFAULT CURRENT_TIMESTAMP, + [updatedAt] DATETIME2 NOT NULL, + [title] VARCHAR(255) NOT NULL, + [content] NVARCHAR(1000), + [published] BIT NOT NULL CONSTRAINT [Post_published_df] DEFAULT 0, + [authorId] INT NOT NULL, + CONSTRAINT [Post_pkey] PRIMARY KEY ([id]) +); + +CREATE TABLE [dbo].[Profile] ( + [id] INT NOT NULL IDENTITY(1,1), + [bio] NVARCHAR(1000), + [userId] INT NOT NULL, + CONSTRAINT [Profile_pkey] PRIMARY KEY ([id]), + CONSTRAINT [Profile_userId_key] UNIQUE ([userId]) +); + +CREATE TABLE [dbo].[User] ( + [id] INT NOT NULL IDENTITY(1,1), + [email] NVARCHAR(1000) NOT NULL, + [name] NVARCHAR(1000), + CONSTRAINT [User_pkey] PRIMARY KEY ([id]), + CONSTRAINT [User_email_key] UNIQUE ([email]) +); + +ALTER TABLE [dbo].[Post] ADD CONSTRAINT [Post_authorId_fkey] FOREIGN KEY ([authorId]) REFERENCES [dbo].[User]([id]) ON DELETE NO ACTION ON UPDATE CASCADE; + +ALTER TABLE [dbo].[Profile] ADD CONSTRAINT [Profile_userId_fkey] FOREIGN KEY ([userId]) REFERENCES [dbo].[User]([id]) ON DELETE NO ACTION ON UPDATE CASCADE; +``` + + + + + +```sql file=prisma/migrations/0_init/migration.sql +CREATE TABLE "User" ( + id INT8 PRIMARY KEY DEFAULT unique_rowid(), + name STRING(255), + email STRING(255) UNIQUE NOT NULL +); + +CREATE TABLE "Post" ( + id INT8 PRIMARY KEY DEFAULT unique_rowid(), + title STRING(255) UNIQUE NOT NULL, + "createdAt" TIMESTAMP NOT NULL DEFAULT now(), + content STRING, + published BOOLEAN NOT NULL DEFAULT false, + "authorId" INT8 NOT NULL, + FOREIGN KEY ("authorId") REFERENCES "User"(id) +); + +CREATE TABLE "Profile" ( + id INT8 PRIMARY KEY DEFAULT unique_rowid(), + bio STRING, + "userId" INT8 UNIQUE NOT NULL, + FOREIGN KEY ("userId") REFERENCES "User"(id) +); +``` + + + +Review the SQL migration file to ensure everything is correct. + +Next, mark the migration as applied using `prisma migrate resolve` with the `--applied` argument. + +```terminal +npx prisma migrate resolve --applied 0_init +``` + +The command will mark `0_init` as applied by adding it to the `_prisma_migrations` table. + +You now have a baseline for your current database schema. To make further changes to your database schema, you can update your Prisma schema and use `prisma migrate dev` to apply the changes to your database. + + + + + + + Introspection + + + + Install Prisma Client + + + + + + + + + + + + Introspection + + + + Install Prisma Client + + + + + + + + + + + + Introspection + + + + Install Prisma Client + + + + + + + + + + + + Introspection + + + + Install Prisma Client + + + + + + + + + + + + Introspection + + + + Install Prisma Client + + + + + + + + + + + + Introspection + + + + Install Prisma Client + + + + + + + + + + + + Introspection + + + + Install Prisma Client + + + + + + + + + + + + Introspection + + + + Install Prisma Client + + + + + diff --git a/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/200-install-prisma-client.mdx b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/200-install-prisma-client.mdx new file mode 100644 index 0000000000..d425e1763c --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/200-install-prisma-client.mdx @@ -0,0 +1,290 @@ +--- +title: 'Install Prisma Client' +metaTitle: 'Install Prisma Client' +metaDescription: 'Install and generate Prisma Client in your project' +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['postgresql', 'mysql', 'sqlserver', 'planetscale', 'cockroachdb'] +toc: false +--- + +## Install and generate Prisma Client + +To get started with Prisma Client, you need to install the `@prisma/client` package: + +```terminal copy +npm install @prisma/client +``` + +Notice that the [`@prisma/client` node module](/orm/prisma-client/setup-and-configuration/generating-prisma-client#the-prismaclient-npm-package) references a folder named `.prisma/client`. The `.prisma/client` folder contains your generated Prisma Client, and is modified each time you change the schema and run the following command: + +```terminal copy +npx prisma generate +``` + +This command reads your Prisma schema and generates your Prisma Client library: + +![Install and generate Prisma Client](/img/getting-started/prisma-client-install-and-generate.png) + +The `@prisma/client` node module references a folder named `.prisma/client`, which contains your unique, generated Prisma Client: + +![The .prisma and @prisma folders](/img/getting-started/prisma-client-node-module.png) + + + + + + + Baseline your database + + + + Querying the database + + + + + + + + + + + + Baseline your database + + + + Querying the database + + + + + + + + + + + + Introspection + + + + Querying the database + + + + + + + + + + + + Baseline your database + + + + Querying the database + + + + + + + + + + + + Baseline your database + + + + Querying the database + + + + + + + + + + + + Baseline your database + + + + Querying the database + + + + + + + + + + + + Baseline your database + + + + Querying the database + + + + + + + + + + + + Introspection + + + + Querying the database + + + + + + + + + + + + Baseline your database + + + + Querying the database + + + + + + + + + + + + Baseline your database + + + + Querying the database + + + + + diff --git a/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/250-querying-the-database.mdx b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/250-querying-the-database.mdx new file mode 100644 index 0000000000..96c378cdef --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/250-querying-the-database.mdx @@ -0,0 +1,641 @@ +--- +title: 'Querying the database' +metaTitle: 'Querying the database' +metaDescription: 'Write data to and query the database' +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['postgresql', 'mysql', 'sqlserver', 'planetscale', 'cockroachdb'] +toc: false +--- + +## Write your first query with Prisma Client + +Now that you have generated Prisma Client, you can start writing queries to read and write data in your database. + +If you're building a REST API, you can use Prisma Client in your route handlers to read and write data in the database based on incoming HTTP requests. If you're building a GraphQL API, you can use Prisma Client in your resolvers to read and write data in the database based on incoming queries and mutations. + +For the purpose of this guide however, you'll just create a plain Node.js script to learn how to send queries to your database using Prisma Client. Once you have an understanding of how the API works, you can start integrating it into your actual application code (e.g. REST route handlers or GraphQL resolvers). + + + +Create a new file named `index.ts` and add the following code to it: + +```ts file=index.ts +import { PrismaClient } from '@prisma/client' + +const prisma = new PrismaClient() + +async function main() { + // ... you will write your Prisma Client queries here +} + +main() + .then(async () => { + await prisma.$disconnect() + }) + .catch(async (e) => { + console.error(e) + await prisma.$disconnect() + process.exit(1) + }) +``` + + + + + +Create a new file named `index.js` and add the following code to it: + +```js file=index.js +const { PrismaClient } = require('@prisma/client') + +const prisma = new PrismaClient() + +async function main() { + // ... you will write your Prisma Client queries here +} + +main() + .then(async () => { + await prisma.$disconnect() + }) + .catch(async (e) => { + console.error(e) + await prisma.$disconnect() + process.exit(1) + }) +``` + + + +Here's a quick overview of the different parts of the code snippet: + +1. Import the `PrismaClient` constructor from the `@prisma/client` node module +1. Instantiate `PrismaClient` +1. Define an `async` function named `main` to send queries to the database +1. Call the `main` function +1. Close the database connections when the script terminates + +Depending on what your models look like, the Prisma Client API will look different as well. For example, if you have a `User` model, your `PrismaClient` instance exposes a property called `user` on which you can call [CRUD](/orm/prisma-client/queries/crud) methods like `findMany`, `create` or `update`. The property is named after the model, but the first letter is lowercased (so for the `Post` model it's called `post`, for `Profile` it's called `profile`). + +The following examples are all based on the models in the Prisma schema. + +Inside the `main` function, add the following query to read all `User` records from the database and print the result: + + + +```ts file=index.ts +async function main() { + const allUsers = await prisma.user.findMany() + console.log(allUsers) +} +``` + + + + + +```js file=index.js +async function main() { + const allUsers = await prisma.user.findMany() + console.log(allUsers) +} +``` + + + + + +Now run the code with your current TypeScript setup. If you're using `ts-node`, you can run it like this: + +```terminal copy +npx ts-node index.ts +``` + + + + + +Now run the code with this command: + +```terminal copy +node index.js +``` + + + +If you created a database using the schema from the database introspection step, the query should print an empty array because there are no `User` records in the database yet. + +```no-copy +[] +``` + +If you introspected an existing database with records, the query should return an array of JavaScript objects. + +## Write data into the database + +The `findMany` query you used in the previous section only _reads_ data from the database. In this section, you'll learn how to write a query to _write_ new records into the `Post` and `User` tables. + +Adjust the `main` function to send a `create` query to the database: + + + +```ts file=index.ts +async function main() { + await prisma.user.create({ + data: { + name: 'Alice', + email: 'alice@prisma.io', + posts: { + create: { title: 'Hello World' }, + }, + profile: { + create: { bio: 'I like turtles' }, + }, + }, + }) + + const allUsers = await prisma.user.findMany({ + include: { + posts: true, + profile: true, + }, + }) + console.dir(allUsers, { depth: null }) +} +``` + + + + + +```js file=index.js +async function main() { + await prisma.user.create({ + data: { + name: 'Alice', + email: 'alice@prisma.io', + posts: { + create: { title: 'Hello World' }, + }, + profile: { + create: { bio: 'I like turtles' }, + }, + }, + }) + + const allUsers = await prisma.user.findMany({ + include: { + posts: true, + profile: true, + }, + }) + console.dir(allUsers, { depth: null }) +} +``` + + + +This code creates a new `User` record together with new `Post` and `Profile` records using a [nested write](/orm/prisma-client/queries/relation-queries#nested-writes) query. The `User` record is connected to the two other ones via the `Post.author` ↔ `User.posts` and `Profile.user` ↔ `User.profile` [relation fields](/orm/prisma-schema/data-model/relations#relation-fields) respectively. + +Notice that you're passing the [`include`](/orm/prisma-client/queries/select-fields#include-relations-and-select-relation-fields) option to `findMany` which tells Prisma Client to include the `posts` and `profile` relations on the returned `User` objects. + + + +Run the code with your current TypeScript setup. If you're using `ts-node`, you can run it like this: + +```terminal copy +npx ts-node index.ts +``` + + + + + +Run the code with this command: + +```terminal copy +node index.js +``` + + + +Before moving on to the next section, you'll "publish" the `Post` record you just created using an `update` query. Adjust the `main` function as follows: + + + +```ts file=index.ts +async function main() { + const post = await prisma.post.update({ + where: { id: 1 }, + data: { published: true }, + }) + console.log(post) +} +``` + + + + + +```js file=index.js +async function main() { + const post = await prisma.post.update({ + where: { id: 1 }, + data: { published: true }, + }) + console.log(post) +} +``` + + + + + +```ts file=index.ts +async function main() { + const post = await prisma.post.update({ + where: { id: 1 }, + data: { published: true }, + }) + console.log(post) +} +``` + + + + + +```js file=index.js +async function main() { + const post = await prisma.post.update({ + where: { id: 1 }, + data: { published: true }, + }) + console.log(post) +} +``` + + + + + +```ts file=index.ts +async function main() { + const post = await prisma.post.update({ + where: { id: 1 }, + data: { published: true }, + }) + console.log(post) +} +``` + + + + + +```js file=index.js +async function main() { + const post = await prisma.post.update({ + where: { id: 1 }, + data: { published: true }, + }) + console.log(post) +} +``` + + + + + +```ts file=index.ts +async function main() { + const post = await prisma.post.update({ + where: { id: 1 }, + data: { published: true }, + }) + console.log(post) +} +``` + + + + + +```js file=index.js +async function main() { + const post = await prisma.post.update({ + where: { id: 1 }, + data: { published: true }, + }) + console.log(post) +} +``` + + + + + +```ts file=index.ts +async function main() { + const post = await prisma.post.update({ + where: { title: 'Hello World' }, + data: { published: true }, + }) + console.log(post) +} +``` + + + + + +```js file=index.js +async function main() { + const post = await prisma.post.update({ + where: { title: 'Hello World' }, + data: { published: true }, + }) + console.log(post) +} +``` + + + + + +Run the code with your current TypeScript setup. If you're using `ts-node`, you can run it like this: + +```terminal copy +npx ts-node index.ts +``` + + + + + +Now run the code using the same command as before: + +```terminal copy +node index.js +``` + + + + + + + + + Install Prisma Client + + + + Evolve your schema + + + + + + + + + + + + Install Prisma Client + + + + Evolve your schema + + + + + + + + + + + + Install Prisma Client + + + Next Steps + + + + + + + + + + + + Install Prisma Client + + + + Evolve your schema + + + + + + + + + + + + Install Prisma Client + + + + Evolve your schema + + + + + + + + + + + + Install Prisma Client + + + + Evolve your schema + + + + + + + + + + + + Install Prisma Client + + + + Evolve your schema + + + + + + + + + + + + Install Prisma Client + + + + Next Steps + + + + + + + + + + + + Install Prisma Client + + + + Evolve your schema + + + + + + + + + + + + Install Prisma Client + + + + Evolve your schema + + + + + diff --git a/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/275-evolve-your-schema.mdx b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/275-evolve-your-schema.mdx new file mode 100644 index 0000000000..79d450cc4e --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/275-evolve-your-schema.mdx @@ -0,0 +1,402 @@ +--- +title: 'Evolve your schema' +metaTitle: 'Evolve your Prisma schema with Prisma Migrate' +metaDescription: 'Evolve your Prisma schema with Prisma Migrate' +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['postgresql', 'mysql', 'sqlserver', 'cockroachdb'] +toc: false +--- + +## Add a `Tag` model to your schema + +In this section, you will evolve your Prisma schema and then generate and apply the migration to your database with [`prisma migrate dev`](/orm/reference/prisma-cli-reference#migrate-dev). + +For the purpose of this guide, we'll make the following changes to the Prisma schema: + +1. Create a new model called `Tag` with the following fields: + - `id`: an auto-incrementing integer that will be the primary key for the model + - `name`: a non-null `String` + - `posts`: an implicit many-to-many relation field that links to the `Post` model +2. Update the `Post` model with a `tags` field with an implicit many-to-many relation field that links to the `Tag` model + +Once you've made the changes to your schema, your schema should resemble the one below: + +```prisma file=prisma/schema.prisma highlight=9,27-31;edit +model Post { + id Int @id @default(autoincrement()) + title String @db.VarChar(255) + createdAt DateTime @default(now()) @db.Timestamp(6) + content String? + published Boolean @default(false) + authorId Int + user User @relation(fields: [authorId], references: [id]) + tags Tag[] +} + +model Profile { + id Int @id @default(autoincrement()) + bio String? + userId Int @unique + user User @relation(fields: [userId], references: [id]) +} + +model User { + id Int @id @default(autoincrement()) + name String? @db.VarChar(255) + email String @unique @db.VarChar(255) + post Post[] + profile Profile? +} + +model Tag { + id Int @id @default(autoincrement()) + name String + posts Post[] +} +``` + +To apply your Prisma schema changes to your database, use the `prisma migrate dev` CLI command: + +```terminal copy +npx prisma migrate dev --name tags-model +``` + +This command will: + +1. Create a new SQL migration file for the migration +1. Apply the generated SQL migration to the database +1. Regenerate Prisma Client + +The following migration will be generated and saved in your `prisma/migrations` folder: + + + +```sql file=prisma/migrations/TIMESTAMP_tags_model.sql + -- CreateTable +CREATE TABLE "Tag" ( + "id" SERIAL NOT NULL, + "name" VARCHAR(255) NOT NULL, + + CONSTRAINT "Tag_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "_PostToTag" ( + "A" INTEGER NOT NULL, + "B" INTEGER NOT NULL +); + +-- CreateIndex +CREATE UNIQUE INDEX "_PostToTag_AB_unique" ON "_PostToTag"("A", "B"); + +-- CreateIndex +CREATE INDEX "_PostToTag_B_index" ON "_PostToTag"("B"); + +-- AddForeignKey +ALTER TABLE "_PostToTag" ADD CONSTRAINT "_PostToTag_A_fkey" FOREIGN KEY ("A") REFERENCES "Post"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_PostToTag" ADD CONSTRAINT "_PostToTag_B_fkey" FOREIGN KEY ("B") REFERENCES "Tag"("id") ON DELETE CASCADE ON UPDATE CASCADE; +``` + + + + + +```sql file=prisma/migrations/TIMESTAMP_tags_model.sql + -- CreateTable +CREATE TABLE "Tag" ( + "id" SERIAL NOT NULL, + "name" VARCHAR(255) NOT NULL, + + CONSTRAINT "Tag_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "_PostToTag" ( + "A" INTEGER NOT NULL, + "B" INTEGER NOT NULL +); + +-- CreateIndex +CREATE UNIQUE INDEX "_PostToTag_AB_unique" ON "_PostToTag"("A", "B"); + +-- CreateIndex +CREATE INDEX "_PostToTag_B_index" ON "_PostToTag"("B"); + +-- AddForeignKey +ALTER TABLE "_PostToTag" ADD CONSTRAINT "_PostToTag_A_fkey" FOREIGN KEY ("A") REFERENCES "Post"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_PostToTag" ADD CONSTRAINT "_PostToTag_B_fkey" FOREIGN KEY ("B") REFERENCES "Tag"("id") ON DELETE CASCADE ON UPDATE CASCADE; +``` + + + + + +```sql file=prisma/migrations/TIMESTAMP_tags_model.sql + -- CreateTable +CREATE TABLE [dbo].[Tag] ( + [id] SERIAL NOT NULL, + [name] VARCHAR(255) NOT NULL, + + CONSTRAINT [Tag_pkey] PRIMARY KEY ([id]) +); + +-- CreateTable +CREATE TABLE [dbo].[_PostToTag] ( + [A] INTEGER NOT NULL, + [B] INTEGER NOT NULL +); + +-- CreateIndex +CREATE UNIQUE INDEX [_PostToTag_AB_unique] ON _PostToTag([A], [B]); + +-- CreateIndex +CREATE INDEX [_PostToTag_B_index] ON [_PostToTag]([B]); + +-- AddForeignKey +ALTER TABLE [dbo].[_PostToTag] ADD CONSTRAINT [_PostToTag_A_fkey] FOREIGN KEY ([A]) REFERENCES [dbo].[Post]([id]) ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE [dbo].[_PostToTag] ADD CONSTRAINT [_PostToTag_B_fkey] FOREIGN KEY ([B]) REFERENCES [dbo].[Tag]([id]) ON DELETE CASCADE ON UPDATE CASCADE; +``` + + + + + +```sql file=prisma/migrations/TIMESTAMP_tags_model.sql +-- CreateTable +CREATE TABLE Tag ( + id SERIAL NOT NULL, + name VARCHAR(255) NOT NULL, + + CONSTRAINT Tag_pkey PRIMARY KEY (id) +); + +-- CreateTable +CREATE TABLE _PostToTag ( + A INTEGER NOT NULL, + B INTEGER NOT NULL +); + +-- CreateIndex +CREATE UNIQUE INDEX _PostToTag_AB_unique ON _PostToTag(A, B); + +-- CreateIndex +CREATE INDEX _PostToTag_B_index ON _PostToTag(B); + +-- AddForeignKey +ALTER TABLE _PostToTag ADD CONSTRAINT _PostToTag_A_fkey FOREIGN KEY (A) REFERENCES Post(id) ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE _PostToTag ADD CONSTRAINT _PostToTag_B_fkey FOREIGN KEY (B) REFERENCES Tag(id) ON DELETE CASCADE ON UPDATE CASCADE; +``` + + + +Congratulations, you just evolved your database with Prisma Migrate πŸš€ + + + + + + Querying the database + + + + Next steps + + + + + + + + + + + + Querying the database + + + + Next steps + + + + + + + + + + + + Querying the database + + + + Next steps + + + + + + + + + + + + Querying the database + + + + Next steps + + + + + + + + + + + + Querying the database + + + + Next steps + + + + + + + + + + + + Querying the database + + + + Next steps + + + + + + + + + + + + Querying the database + + + + Next steps + + + + + + + + + + + + Querying the database + + + + Next steps + + + + + diff --git a/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/300-next-steps.mdx b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/300-next-steps.mdx new file mode 100644 index 0000000000..df306cf469 --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/300-next-steps.mdx @@ -0,0 +1,120 @@ +--- +title: 'Next steps' +metaTitle: 'Next steps' +metaDescription: 'Next steps to take now that you have successfully added Prisma to your project' +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['postgresql', 'mysql', 'sqlserver', 'planetscale', 'cockroachdb'] +toc: false +--- + +## Next steps + +This section lists a number of potential next steps you can now take from here. Feel free to explore these or read the [Introduction](/orm/overview/introduction/what-is-prisma) page to get a high-level overview of Prisma. + +### Continue exploring the Prisma Client API + +You can send a variety of queries with the Prisma Client API. Check out the [API reference](/orm/prisma-client) and use your existing database setup from this guide to try them out. + +:::tip + +You can use your editor's auto-completion feature to learn about the different API calls and the arguments it takes. Auto-completion is commonly invoked by hitting CTRL+SPACE on your keyboard. + +::: + +
+Expand for more Prisma Client API examples + +Here are a few suggestions for a number of more queries you can send with Prisma Client: + +**Filter all `Post` records that contain `"hello"`** + +```js +const filteredPosts = await prisma.post.findMany({ + where: { + OR: [ + { title: { contains: "hello" }, + { content: { contains: "hello" }, + ], + }, +}) +``` + +**Create a new `Post` record and connect it to an existing `User` record** + +```js +const post = await prisma.post.create({ + data: { + title: 'Join us for Prisma Day 2020', + author: { + connect: { email: 'alice@prisma.io' }, + }, + }, +}) +``` + +**Use the fluent relations API to retrieve the `Post` records of a `User` by traversing the relations** + +```js +const posts = await prisma.profile + .findUnique({ + where: { id: 1 }, + }) + .user() + .posts() +``` + +**Delete a `User` record** + +```js +const deletedUser = await prisma.user.delete({ + where: { email: 'sarah@prisma.io' }, +}) +``` + +
+ +### Explore the data in Prisma Studio + +Prisma Studio is a visual editor for the data in your database. Run `npx prisma studio` in your terminal. + +### Change the database schema (e.g. add more tables) + +To evolve the app, you need to follow the same flow of the tutorial: + +1. Manually adjust your database schema using SQL +1. Re-introspect your database +1. Optionally re-configure your Prisma Client API +1. Re-generate Prisma Client + +![Introspect workflow](/img/getting-started/prisma-evolve-app-workflow.png) + +### Try a Prisma example + +The [`prisma-examples`](https://github.com/prisma/prisma-examples/) repository contains a number of ready-to-run examples: + + + + + +| Demo | Stack | Description | +| :------------------------------------------------------------------------------------------------------------------ | :----------- | --------------------------------------------------------------------------------------------------- | +| [`rest-nextjs-api-routes`](https://github.com/prisma/prisma-examples/tree/latest/typescript/rest-nextjs-api-routes) | Fullstack | Simple [Next.js](https://nextjs.org/) app (React) with a REST API | +| [`graphql-nextjs`](https://github.com/prisma/prisma-examples/tree/latest/typescript/graphql-nextjs) | Fullstack | Simple [Next.js](https://nextjs.org/) app (React) with a GraphQL API | +| [`graphql-apollo-server`](https://github.com/prisma/prisma-examples/tree/latest/typescript/graphql-apollo-server) | Backend only | Simple GraphQL server based on [`apollo-server`](https://www.apollographql.com/docs/apollo-server/) | +| [`rest-express`](https://github.com/prisma/prisma-examples/tree/latest/typescript/rest-express) | Backend only | Simple REST API with Express.JS | +| [`grpc`](https://github.com/prisma/prisma-examples/tree/latest/typescript/grpc) | Backend only | Simple gRPC API | + + + + + +| Demo | Stack | Description | +| :---------------------------------------------------------------------------------------------------------------- | :----------- | :-------------------------------------------------------------------------------------------------- | +| [`rest-nextjs`](https://github.com/prisma/prisma-examples/tree/latest/javascript/rest-nextjs) | Fullstack | Simple [Next.js](https://nextjs.org/) app (React) with a REST API | +| [`graphql-apollo-server`](https://github.com/prisma/prisma-examples/tree/latest/javascript/graphql-apollo-server) | Backend only | Simple GraphQL server based on [`apollo-server`](https://www.apollographql.com/docs/apollo-server/) | +| [`rest-express`](https://github.com/prisma/prisma-examples/tree/latest/javascript/rest-express) | Backend only | Simple REST API with Express.JS | +| [`grpc`](https://github.com/prisma/prisma-examples/tree/latest/javascript/grpc) | Backend only | Simple gRPC API | + + + + diff --git a/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/index.mdx b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/index.mdx new file mode 100644 index 0000000000..b2ba6426ce --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/index.mdx @@ -0,0 +1,276 @@ +--- +title: 'Relational databases' +metaTitle: 'Add Prisma to an existing project that uses a relational database (15 min)' +metaDescription: 'Learn how to add Prisma to an existing Node.js or TypeScript project by connecting it to your relational database and generating a Prisma Client for database access.' +duration: '15 min' +toc: false +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['postgresql', 'mysql', 'sqlserver', 'planetscale', 'cockroachdb'] +--- + + + +Learn how to add Prisma to an existing Node.js or TypeScript project by connecting it to your database and generating a Prisma Client for database access. The following tutorial introduces you to the [Prisma CLI](/orm/tools/prisma-cli), [Prisma Client](/orm/prisma-client), and [Prisma Introspection](/orm/prisma-schema/introspection). + + + +:::tip + +
+ +If you're migrating to Prisma from another ORM, see our [Migrate from TypeORM](/orm/more/migrating-to-prisma/migrate-from-typeorm) or [Migrate from Sequelize](/orm/more/migrating-to-prisma/migrate-from-sequelize) migration guides. + +
+::: + +## Prerequisites + +In order to successfully complete this guide, you need: + + + +- an existing Node.js project with a `package.json` +- [Node.js](https://nodejs.org/en/) installed on your machine +- a [PostgreSQL](https://www.postgresql.org/) database server running and a database with at least one table + + + + + +- an existing Node.js project with a `package.json` +- [Node.js](https://nodejs.org/en/) installed on your machine +- a [MySQL](https://www.mysql.com/) database server running and a database with at least one table + + + + + +- an existing Node.js project with a `package.json` +- [Node.js](https://nodejs.org/en/) installed on your machine +- a [PlanetScale](https://www.planetscale.com/) database server running and a database with at least one table + + + + + +- [Node.js](https://nodejs.org/en/) installed on your machine +- A [Microsoft SQL Server](https://docs.microsoft.com/en-us/sql/?view=sql-server-ver15) database + - [Microsoft SQL Server on Linux for Docker](/orm/overview/databases/sql-server/sql-server-docker) + - [Microsoft SQL Server on Windows (local)](/orm/overview/databases/sql-server/sql-server-local) + + + + + +- an existing Node.js project with a `package.json` +- [Node.js](https://nodejs.org/en/) installed on your machine +- a [CockroachDB](https://www.cockroachlabs.com) database server running and a database with at least one table + + + +> See [System requirements](/orm/reference/system-requirements) for exact version requirements. + +Make sure you have your database [connection URL](/orm/reference/connection-urls) (that includes your authentication credentials) at hand! If you don't have a database server running and just want to explore Prisma, check out the [Quickstart](/getting-started/quickstart). + +## Set up Prisma + +As a first step, navigate into your project directory that contains the `package.json` file. + +Next, add the Prisma CLI as a development dependency to your project: + +```terminal copy +npm install prisma --save-dev +``` + +You can now invoke the Prisma CLI by prefixing it with `npx`: + +```terminal +npx prisma +``` + + + +See [installation instructions](/orm/tools/prisma-cli#installation) to learn how to install Prisma using a different package manager. + + + +Next, set up your Prisma project by creating your [Prisma schema](/orm/prisma-schema) file template with the following command: + +```terminal copy +npx prisma init +``` + +This command does two things: + +- creates a new directory called `prisma` that contains a file called `schema.prisma`, which contains the Prisma schema with your database connection variable and schema models +- creates the [`.env` file](/orm/more/development-environment/environment-variables/env-files) in the root directory of the project, which is used for defining environment variables (such as your database connection) + + + + + + + Connect your database + + + + + + + + + + + + Connect your database + + + + + + + + + + + + Connect your database + + + + + + + + + + + + Connect your database + + + + + + + + + + + + Connect your database + + + + + + + + + + + + Connect your database + + + + + + + + + + + + Connect your database + + + + + + + + + + + + Connect your database + + + + + + + + + + + + Connect your database + + + + + + + + + + + + Connect your database + + + + + diff --git a/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/120-mongodb/100-connect-your-database.mdx b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/120-mongodb/100-connect-your-database.mdx new file mode 100644 index 0000000000..5e976dcd74 --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/120-mongodb/100-connect-your-database.mdx @@ -0,0 +1,95 @@ +--- +title: 'Connect your database' +metaTitle: 'Connect your database' +metaDescription: 'Connect your database to your project' +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['mongodb'] +toc: false +--- + +## Connecting your database + +To connect your database, you need to set the `url` field of the `datasource` block in your Prisma schema to your database [connection URL](/orm/reference/connection-urls): + +```prisma file=prisma/schema.prisma +datasource db { + provider = "mongodb" + url = env("DATABASE_URL") +} +``` + +In this case, the `url` is [set via an environment variable](/orm/more/development-environment/environment-variables) which is defined in `.env`: + +```bash file=.env +DATABASE_URL="mongodb+srv://test:test@cluster0.ns1yp.mongodb.net/myFirstDatabase" +``` + +You now need to adjust the connection URL to point to your own database. + +The [format of the connection URL](/orm/reference/connection-urls) for your database depends on the database you use. For MongoDB, it looks as follows (the parts spelled all-uppercased are _placeholders_ for your specific connection details): + +```no-lines +mongodb://USERNAME:PASSWORD@HOST:PORT/DATABASE +``` + +Here's a short explanation of each component: + +- `USERNAME`: The name of your database user +- `PASSWORD`: The password for your database user +- `HOST`: The host where a [`mongod`](https://docs.mongodb.com/manual/reference/program/mongod/#mongodb-binary-bin.mongod) (or [`mongos`](https://docs.mongodb.com/manual/reference/program/mongos/#mongodb-binary-bin.mongos)) instance is running +- `PORT`: The port where your database server is running (typically `27017` for MongoDB) +- `DATABASE`: The name of the database + +> If you see the following error: `Error in connector: SCRAM failure: Authentication failed.`, you can specify the source database for the authentication by [adding](https://github.com/prisma/prisma/discussions/9994#discussioncomment-1562283) `?authSource=admin` to the end of the connection string. + + + + + + + Installation + + + + Introspection + + + + + + + + + + + + Installation + + + + Introspection + + + + + diff --git a/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/120-mongodb/125-introspection.mdx b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/120-mongodb/125-introspection.mdx new file mode 100644 index 0000000000..45b0c17ad6 --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/120-mongodb/125-introspection.mdx @@ -0,0 +1,175 @@ +--- +title: 'Introspection' +metaTitle: 'Introspection' +metaDescription: 'Introspection your database with Prisma' +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['mongodb'] +toc: false +--- + +# Introspection + +Prisma introspects a MongoDB schema by sampling the data stored in the given database and inferring the schema of that data. + +For the purposes of illustrating introspection, this guide will help you setup a MongoDB from scratch. But if you have a MongoDB database already, feel free to jump to [Initializing Prisma](#initializing-prisma) in your project. + +## Setting up your Database + +To see this in action, first create a `blog` database with 2 collections: `User` and `Post`. We recommend [MongoDB Compass](https://www.mongodb.com/products/compass) for setting this up: + +![Create a blog database using Compass](/img/getting-started/1-create-database.jpg) + +First, add a user to our `User` collection: + +![Create a user within the User collection](/img/getting-started/2-create-user.jpg) + +Next, add some posts to our `Post` collection. It's important that the ObjectID in `userId` matches the user you created above. + +![Create some posts within the Post collection](/img/getting-started/3-create-posts.jpg) + +## Initializing Prisma + +Now that you have a MongoDB database, the next step is to create a new project and initialize Prisma: + +```terminal copy +mkdir blog +cd blog +npm init -y +npm install -D prisma +npx prisma init +``` + +Initializing Prisma will create a `prisma/schema.prisma` file. Edit this file to use MongoDB: + +```prisma file=prisma/schema.prisma +datasource db { + provider = "mongodb" + url = env("DATABASE_URL") +} + +generator client { + provider = "prisma-client-js" +} +``` + +Next you'll need to adjust your `.env` file to point the `DATABASE_URL` to your MongoDB database + +## Introspecting MongoDB with Prisma + +You're now ready to introspect. Run the following command to introspect your database: + +```terminal copy +npx prisma db pull +``` + +This command introspects our database and writes the inferred schema into your `prisma/schema.prisma` file: + +```prisma file=prisma/schema.prisma +datasource db { + provider = "mongodb" + url = env("DATABASE_URL") +} + +generator client { + provider = "prisma-client-js" +} + +model Post { + id String @id @default(auto()) @map("_id") @db.ObjectId + title String + userId String @db.ObjectId +} + +model User { + id String @id @default(auto()) @map("_id") @db.ObjectId + email String +} +``` + +## Tweaking the Schema + +To be able to join data using Prisma Client, you can add the [`@relation`](/orm/reference/prisma-schema-reference#relation) attributes to our models: + +```prisma file=prisma/schema.prisma highlight=14;add|20;add +datasource db { + provider = "mongodb" + url = env("DATABASE_URL") +} + +generator client { + provider = "prisma-client-js" +} + +model Post { + id String @id @default(auto()) @map("_id") @db.ObjectId + title String + userId String @db.ObjectId + user User @relation(fields: [userId], references: [id]) +} + +model User { + id String @id @default(auto()) @map("_id") @db.ObjectId + email String + posts Post[] +} +``` + +:::tip + +We're actively working on MongoDB introspection. Provide feedback for this feature in [this issue](https://github.com/prisma/prisma/issues/8241). + +::: + +And with that, you're ready to generate Prisma Client. + + + + + + + Connect to your Database + + + + Install Prisma Client + + + + + + + + + + + + Connect to your Database + + + + Install Prisma Client + + + + + diff --git a/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/120-mongodb/200-install-prisma-client.mdx b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/120-mongodb/200-install-prisma-client.mdx new file mode 100644 index 0000000000..8563c7cfb8 --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/120-mongodb/200-install-prisma-client.mdx @@ -0,0 +1,74 @@ +--- +title: 'Install Prisma Client' +metaTitle: 'Install Prisma Client' +metaDescription: 'Install and generate Prisma Client in your project' +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['mongodb'] +toc: false +--- + +## Install and generate Prisma Client + +To get started with Prisma Client, you need to install the `@prisma/client` package: + +```terminal copy +npm install @prisma/client +``` + +The install command invokes `prisma generate` for you which reads your Prisma schema and generates a version of Prisma Client that is _tailored_ to your models. + +![Install and generate Prisma Client](/img/getting-started/prisma-client-install-and-generate.png) + +Whenever you make changes to your Prisma schema in the future, you manually need to invoke `prisma generate` in order to accommodate the changes in your Prisma Client API. + + + + + + + Introspection + + + + Querying the database + + + + + + + + + + + + Introspection + + + + Querying the database + + + + + diff --git a/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/120-mongodb/250-querying-the-database.mdx b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/120-mongodb/250-querying-the-database.mdx new file mode 100644 index 0000000000..06769be5d7 --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/120-mongodb/250-querying-the-database.mdx @@ -0,0 +1,431 @@ +--- +title: 'Querying the database' +metaTitle: 'Querying the database' +metaDescription: 'Write data to and query the database' +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['mongodb'] +toc: false +--- + +## Write your first query with Prisma Client + +Now that you have generated Prisma Client, you can start writing queries to read and write data in your database. For the purpose of this guide, you'll use a plain Node.js script to explore some basic features of Prisma Client. + +If you're building a REST API, you can use Prisma Client in your route handlers to read and write data in the database based on incoming HTTP requests. If you're building a GraphQL API, you can use Prisma Client in your resolvers to read and write data in the database based on incoming queries and mutations. + +For the purpose of this guide however, you'll just create a plain Node.js script to learn how to send queries to your database using Prisma Client. Once you have an understanding of how the API works, you can start integrating it into your actual application code (e.g. REST route handlers or GraphQL resolvers). + + + +Create a new file named `index.ts` and add the following code to it: + +```js file=index.ts copy +import { PrismaClient } from '@prisma/client' + +const prisma = new PrismaClient() + +async function main() { + // ... you will write your Prisma Client queries here +} + +main() + .then(async () => { + await prisma.$disconnect() + }) + .catch(async (e) => { + console.error(e) + await prisma.$disconnect() + process.exit(1) + }) +``` + + + + + +Create a new file named `index.js` and add the following code to it: + +```js file=index.js copy +const { PrismaClient } = require('@prisma/client') + +const prisma = new PrismaClient() + +async function main() { + // ... you will write your Prisma Client queries here +} + +main() + .then(async () => { + await prisma.$disconnect() + }) + .catch(async (e) => { + console.error(e) + await prisma.$disconnect() + process.exit(1) + }) +``` + + + +Here's a quick overview of the different parts of the code snippet: + +1. Import the `PrismaClient` constructor from the `@prisma/client` node module +1. Instantiate `PrismaClient` +1. Define an `async` function named `main` to send queries to the database +1. Connect to the database +1. Call the `main` function +1. Close the database connections when the script terminates + +Inside the `main` function, add the following query to read all `User` records from the database and print the result: + + + +```ts file=index.ts +async function main() { + // ... you will write your Prisma Client queries here ++ const allUsers = await prisma.user.findMany() ++ console.log(allUsers) +} +``` + + + + + +```js file=index.js +async function main() { +- // ... you will write your Prisma Client queries here ++ const allUsers = await prisma.user.findMany() ++ console.log(allUsers) +} +``` + + + +Now run the code with this command: + + + +```terminal copy +npx ts-node index.ts +``` + + + + + +```terminal copy +node index.js +``` + + + +If you introspected an existing database with records, the query should return an array of JavaScript objects. + +## Write data into the database + +The `findMany` query you used in the previous section only _reads_ data from the database (although it was still empty). In this section, you'll learn how to write a query to _write_ new records into the `Post`, `User` and `Comment` tables. + +Adjust the `main` function to send a `create` query to the database: + + + +```ts file=index.ts copy +async function main() { + await prisma.user.create({ + data: { + name: 'Rich', + email: 'hello@prisma.com', + posts: { + create: { + title: 'My first post', + body: 'Lots of really interesting stuff', + slug: 'my-first-post', + }, + }, + }, + }) + + const allUsers = await prisma.user.findMany({ + include: { + posts: true, + }, + }) + console.dir(allUsers, { depth: null }) +} +``` + + + + + +```js file=index.js copy +async function main() { + await prisma.user.create({ + data: { + name: 'Rich', + email: 'hello@prisma.com', + posts: { + create: { + title: 'My first post', + body: 'Lots of really interesting stuff', + slug: 'my-first-post', + }, + }, + }, + }) + + const allUsers = await prisma.user.findMany({ + include: { + posts: true, + }, + }) + console.dir(allUsers, { depth: null }) +} +``` + + + +This code creates a new `User` record together with a new `Post` using a [nested write](/orm/prisma-client/queries/relation-queries#nested-writes) query. The `User` record is connected to the other one via the `Post.author` ↔ `User.posts` [relation fields](/orm/prisma-schema/data-model/relations#relation-fields) respectively. + +Notice that you're passing the [`include`](/orm/prisma-client/queries/select-fields#include-relations-and-select-relation-fields) option to `findMany` which tells Prisma Client to include the `posts` relations on the returned `User` objects. + +Run the code with this command: + + + +```terminal copy +npx ts-node index.ts +``` + + + + + +```terminal copy +node index.js +``` + + + +The output should look similar to this: + +```json5 no-lines +[ + { + id: '60cc9b0e001e3bfd00a6eddf', + email: 'hello@prisma.com', + name: 'Rich', + posts: [ + { + id: '60cc9bad005059d6007f45dd', + slug: 'my-first-post', + title: 'My first post', + body: 'Lots of really interesting stuff', + userId: '60cc9b0e001e3bfd00a6eddf', + }, + ], + }, +] +``` + + + +Also note that `allUsers` is _statically typed_ thanks to [Prisma Client's generated types](/orm/prisma-client/type-safety/operating-against-partial-structures-of-model-types). You can observe the type by hovering over the `allUsers` variable in your editor. It should be typed as follows: + +```ts no-lines +const allUsers: (User & { + posts: Post[] +})[] + +export type Post = { + id: number + title: string + body: string | null + published: boolean + authorId: number | null +} +``` + + + +The query added new records to the `User` and the `Post` collections: + + + +The `id` field in the Prisma schema maps to `_id` in the underlying MongoDB database. + + + +**User** collection + +| **\_id** | **email** | **name** | +| :------------------------- | :------------------- | :------- | +| `60cc9b0e001e3bfd00a6eddf` | `"hello@prisma.com"` | `"Rich"` | + +**Post** collection + +| **\_id** | **createdAt** | **title** | **content** | **published** | **authorId** | +| :------------------------- | :------------------------- | :---------------- | :--------------------------------- | :------------ | :------------------------- | +| `60cc9bad005059d6007f45dd` | `2020-03-21T16:45:01.246Z` | `"My first post"` | `Lots of really interesting stuff` | `false` | `60cc9b0e001e3bfd00a6eddf` | + +> **Note**: The unique identifier in the `authorId` document field on `Post` reference the `_id` document field in the `User` collection, meaning the `_id` value `60cc9b0e001e3bfd00a6eddf` column therefore refers to the first (and only) `User` record in the database. + +Before moving on to the next section, you'll add a couple of comments to the `Post` record you just created using an `update` query. Adjust the `main` function as follows: + + + +```ts file=index.ts copy +async function main() { + await prisma.post.update({ + where: { + slug: 'my-first-post', + }, + data: { + comments: { + createMany: { + data: [ + { comment: 'Great post!' }, + { comment: "Can't wait to read more!" }, + ], + }, + }, + }, + }) + const posts = await prisma.post.findMany({ + include: { + comments: true, + }, + }) + + console.dir(posts, { depth: Infinity }) +} +``` + + + + + +```js file=index.js copy +async function main() { + await prisma.post.update({ + where: { + slug: 'my-first-post', + }, + data: { + comments: { + createMany: { + data: [ + { comment: 'Great post!' }, + { comment: "Can't wait to read more!" }, + ], + }, + }, + }, + }) + const posts = await prisma.post.findMany({ + include: { + comments: true, + }, + }) + + console.dir(posts, { depth: Infinity }) +} +``` + + + + + +Now run the code using the same command as before: + +```terminal copy +npx ts-node index.ts +``` + + + + + +Now run the code using the same command as before: + +```terminal copy +node index.js +``` + + + +You will see the following output: + +```json5 no-lines +[ + { + id: '60cc9bad005059d6007f45dd', + slug: 'my-first-post', + title: 'My first post', + body: 'Lots of really interesting stuff', + userId: '60cc9b0e001e3bfd00a6eddf', + comments: [ + { + id: '60cca420008a21d800578793', + postId: '60cca40300af8bf000f6ca99', + comment: 'Great post!', + }, + { + id: '60cca420008a21d800578794', + postId: '60cca40300af8bf000f6ca99', + comment: "Can't wait to try this!", + }, + ], + }, +] +``` + +Fantastic, you just wrote new data into your database for the first time using Prisma Client πŸš€ + + + + + + + Install Prisma Client + + + + Next Steps + + + + + + + + + + + + Install Prisma Client + + + + Next Steps + + + + + diff --git a/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/120-mongodb/300-next-steps.mdx b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/120-mongodb/300-next-steps.mdx new file mode 100644 index 0000000000..3d796c921c --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/120-mongodb/300-next-steps.mdx @@ -0,0 +1,108 @@ +--- +title: 'Next steps' +metaTitle: 'Next steps' +metaDescription: 'Next steps to take now that you have successfully added Prisma to your project' +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['mongodb'] +toc: false +--- + +## Next steps + +This section lists a number of potential next steps you can now take from here. Feel free to explore these or read the [Introduction](/orm/overview/introduction/what-is-prisma) page to get a high-level overview of Prisma. + +### Continue exploring the Prisma Client API + +You can send a variety of queries with the Prisma Client API. Check out the [API reference](/orm/prisma-client) and use your existing database setup from this guide to try them out. + +:::tip + +You can use your editor's auto-completion feature to learn about the different API calls and the arguments it takes. Auto-completion is commonly invoked by hitting CTRL+SPACE on your keyboard. + +::: + +
+Expand for more Prisma Client API examples + +Here are a few suggestions for a number of more queries you can send with Prisma Client: + +**Filter all `Post` records that contain `"hello"`** + +```js +const filteredPosts = await prisma.post.findMany({ + where: { + OR: [{ title: { contains: 'hello' } }, { body: { contains: 'hello' } }], + }, +}) +``` + +**Create a new `Post` record and connect it to an existing `User` record** + +```js +const post = await prisma.post.create({ + data: { + title: 'Join us for Prisma Day 2020', + slug: 'prisma-day-2020', + body: 'A conference on modern application development and databases.', + user: { + connect: { email: 'hello@prisma.com' }, + }, + }, +}) +``` + +**Use the fluent relations API to retrieve the `Post` records of a `User` by traversing the relations** + +```js +const user = await prisma.comment + .findUnique({ + where: { id: '60ff4e9500acc65700ebf470' }, + }) + .post() + .user() +``` + +**Delete a `User` record** + +```js +const deletedUser = await prisma.user.delete({ + where: { email: 'sarah@prisma.io' }, +}) +``` + +
+ +### Explore the data in Prisma Studio + +Prisma Studio is a visual editor for the data in your database. Run `npx prisma studio` in your terminal. + +### Try a Prisma example + +The [`prisma-examples`](https://github.com/prisma/prisma-examples/) repository contains a number of ready-to-run examples: + + + + + +| Demo | Stack | Description | +| :------------------------------------------------------------------------------------------------------------------ | :----------- | --------------------------------------------------------------------------------------------------- | +| [`rest-nextjs-api-routes`](https://github.com/prisma/prisma-examples/tree/latest/typescript/rest-nextjs-api-routes) | Fullstack | Simple [Next.js](https://nextjs.org/) app (React) with a REST API | +| [`graphql-nextjs`](https://github.com/prisma/prisma-examples/tree/latest/typescript/graphql-nextjs) | Fullstack | Simple [Next.js](https://nextjs.org/) app (React) with a GraphQL API | +| [`graphql-apollo-server`](https://github.com/prisma/prisma-examples/tree/latest/typescript/graphql-apollo-server) | Backend only | Simple GraphQL server based on [`apollo-server`](https://www.apollographql.com/docs/apollo-server/) | +| [`rest-express`](https://github.com/prisma/prisma-examples/tree/latest/typescript/rest-express) | Backend only | Simple REST API with Express.JS | +| [`grpc`](https://github.com/prisma/prisma-examples/tree/latest/typescript/grpc) | Backend only | Simple gRPC API | + + + + + +| Demo | Stack | Description | +| :---------------------------------------------------------------------------------------------------------------- | :----------- | :-------------------------------------------------------------------------------------------------- | +| [`rest-nextjs`](https://github.com/prisma/prisma-examples/tree/latest/javascript/rest-nextjs) | Fullstack | Simple [Next.js](https://nextjs.org/) app (React) with a REST API | +| [`graphql-apollo-server`](https://github.com/prisma/prisma-examples/tree/latest/javascript/graphql-apollo-server) | Backend only | Simple GraphQL server based on [`apollo-server`](https://www.apollographql.com/docs/apollo-server/) | +| [`rest-express`](https://github.com/prisma/prisma-examples/tree/latest/javascript/rest-express) | Backend only | Simple REST API with Express.JS | +| [`grpc`](https://github.com/prisma/prisma-examples/tree/latest/javascript/grpc) | Backend only | Simple gRPC API | + + + + diff --git a/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/120-mongodb/index.mdx b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/120-mongodb/index.mdx new file mode 100644 index 0000000000..d9a814ca44 --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/120-mongodb/index.mdx @@ -0,0 +1,102 @@ +--- +title: 'MongoDB' +metaTitle: 'Add Prisma to an existing MongoDB project (15 min)' +metaDescription: 'Learn how to add Prisma to an existing Node.js or TypeScript project by connecting it to your MongoDB database and generating a Prisma Client for database access.' +duration: '15 min' +toc: false +langSwitcher: ['typescript', 'node'] +dbSwitcher: ['mongodb'] +--- + + + +Learn how to add Prisma to an existing Node.js or TypeScript project by connecting it to your database and generating a Prisma Client for database access. The following tutorial introduces you to [Prisma CLI](/orm/tools/prisma-cli), [Prisma Client](/orm/prisma-client), and [Prisma Introspection](/orm/prisma-schema/introspection). + + + +:::tip + +
+ +If you're migrating to Prisma from Mongoose, see our [Migrate from Mongoose guide](/orm/more/migrating-to-prisma/migrate-from-mongoose). + +
+::: + +## Prerequisites + +In order to successfully complete this guide, you need: + +- [Node.js](https://nodejs.org/en/) installed on your machine +- Access to a MongoDB 4.2+ server with a replica set deployment. We recommend using [MongoDB Atlas](https://www.mongodb.com/cloud/atlas). + + + + The MongoDB database connector uses transactions to support nested writes. TransactionsΒ **requires**Β aΒ [replica set](https://docs.mongodb.com/manual/tutorial/deploy-replica-set/)Β deployment. The easiest way to deploy a replica set is withΒ [Atlas](https://docs.atlas.mongodb.com/getting-started/). It's free to get started. + + + +Make sure you have your database [connection URL](/orm/reference/connection-urls) (that includes your authentication credentials) at hand! If you don't have a database server running and just want to explore Prisma, check out the [Quickstart](/getting-started/quickstart). + +> See [System requirements](/orm/reference/system-requirements) for exact version requirements. + +## Set up Prisma + +As a first step, navigate into it your project directory that contains the `package.json` file. + +Next, add the Prisma CLI as a development dependency to your project: + +```terminal copy +npm install prisma --save-dev +``` + +You can now invoke the Prisma CLI by prefixing it with `npx`: + +```terminal +npx prisma +``` + +Next, set up your Prisma project by creating your [Prisma schema](/orm/prisma-schema) file template with the following command: + +```terminal copy +npx prisma init +``` + +This command does two things: + +- creates a new directory called `prisma` that contains a file called `schema.prisma`, which contains the Prisma schema with your database connection variable and schema models +- creates the [`.env` file](/orm/more/development-environment/environment-variables/env-files) in the root directory of the project, which is used for defining environment variables (such as your database connection) + + + + + + + Connect your database + + + + + + + + + + + + Connect your database + + + + + diff --git a/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/index.mdx b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/index.mdx new file mode 100644 index 0000000000..cd8dc40bca --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/200-add-to-existing-project/index.mdx @@ -0,0 +1,16 @@ +--- +title: 'Add to existing project' +metaTitle: 'Add Prisma to an existing project' +metaDescription: 'Learn how to add Prisma to an existing Node.js or TypeScript project by connecting it to your database of choice and generating a Prisma Client for database access.' +toc: false +--- + + + +Include Prisma in an existing project with the following documentation, which explains some core concepts as it guides you through integrating Prisma into your workflow. + + + +## In this section + + diff --git a/docs/100-getting-started/02-setup-prisma/index.mdx b/docs/100-getting-started/02-setup-prisma/index.mdx new file mode 100644 index 0000000000..bd4d38e269 --- /dev/null +++ b/docs/100-getting-started/02-setup-prisma/index.mdx @@ -0,0 +1,17 @@ +--- +title: 'Set up Prisma ORM' +metaTitle: 'Set up Prisma ORM' +metaDescription: 'Get started with Prisma ORM and your favorite database. Learn about data modeling, migrations and querying.' +toc: false +staticLink: true +--- + + + +Start from scratch or add Prisma to an existing project. The following tutorials introduce you to the [Prisma CLI](/orm/tools/prisma-cli), [Prisma Client](/orm/prisma-client), and [Prisma Migrate](/orm/prisma-migrate). + + + +## In this section + + diff --git a/docs/100-getting-started/index.mdx b/docs/100-getting-started/index.mdx new file mode 100644 index 0000000000..edb1695ac1 --- /dev/null +++ b/docs/100-getting-started/index.mdx @@ -0,0 +1,174 @@ +--- +title: 'Get Started' +metaTitle: 'Get started with Prisma' +metaDescription: 'Build data-driven applications with ease using Prisma ORM, add connection pooling or global caching with Prisma Accelerate or subscribe to database changes in real-time with Prisma Pulse.' +hide_title: true +tocDepth: 1 +--- + +import { + Bolt, + BorderBox, + BoxTitle, + Database, + Grid, + LinkCard, + List, + SignalStream, + SquareLogo, +} from '@site/src/components/GettingStarted'; + + + + + +Get started + +Welcome πŸ‘‹ + +Explore our products that make it easy to build and scale data-driven applications: + +[**Prisma ORM**](/orm/overview/introduction/what-is-prisma) is a next-generation Node.js and TypeScript ORM that unlocks a new level of developer experience when working with databases thanks to its intuitive data model, automated migrations, type-safety & auto-completion. + +[**Prisma Accelerate**](/accelerate/what-is-accelerate) is a global database cache with scalable connection pooling. + +[**Prisma Pulse**](/pulse/what-is-pulse) allows you to build reactive, real-time applications in a type-safe manner. + + + + + +## Prisma ORM + +Add Prisma ORM to your application in a few minutes to start modeling your data, run schema migrations and query your database. + +### Explore quickly with a SQLite database + +_These options don't require you to have your own database running._ + + + + + + +### Choose an option to get started with your own database + +_Select one of these options if you want to connect Prisma ORM to your own database._ + + + + Set up Prisma ORM **from scratch** with your favorite database and learn basic workflows like data modeling, querying, and migrations. + + + + + + + + + + +

+ Get started with Prisma ORM and your existing database by + introspecting your database schema and learn how to query your database. +

+ + + + + + + + +
+
+ +## Prisma Accelerate + +Make your app faster by scaling your database connections and caching database results at the edge with Prisma Accelerate. + + + + + + +## Prisma Pulse + +Build real-time applications by subscribing to data changes in your database using Prisma Pulse. + + + + diff --git a/package-lock.json b/package-lock.json index ca7e5975f6..9cb87fc58f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,8 @@ "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0", "react": "^18.0.0", - "react-dom": "^18.0.0" + "react-dom": "^18.0.0", + "styled-components": "^6.1.8" }, "devDependencies": { "@docusaurus/module-type-aliases": "^3.1.1", @@ -2882,6 +2883,24 @@ "node": ">=18.0" } }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "node_modules/@emotion/unitless": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", + "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" + }, "node_modules/@esbuild-plugins/node-globals-polyfill": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@esbuild-plugins/node-globals-polyfill/-/node-globals-polyfill-0.2.3.tgz", @@ -4131,6 +4150,11 @@ "@types/node": "*" } }, + "node_modules/@types/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw==" + }, "node_modules/@types/unist": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", @@ -4952,6 +4976,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", @@ -5605,6 +5637,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "engines": { + "node": ">=4" + } + }, "node_modules/css-declaration-sorter": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", @@ -5716,6 +5756,16 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, "node_modules/css-tree": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", @@ -14012,6 +14062,70 @@ "inline-style-parser": "0.1.1" } }, + "node_modules/styled-components": { + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.8.tgz", + "integrity": "sha512-PQ6Dn+QxlWyEGCKDS71NGsXoVLKfE1c3vApkvDYS5KAK+V8fNWGhbSUEo9Gg2iaID2tjLXegEW3bZDUGpofRWw==", + "dependencies": { + "@emotion/is-prop-valid": "1.2.1", + "@emotion/unitless": "0.8.0", + "@types/stylis": "4.2.0", + "css-to-react-native": "3.2.0", + "csstype": "3.1.2", + "postcss": "8.4.31", + "shallowequal": "1.1.0", + "stylis": "4.3.1", + "tslib": "2.5.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" + }, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0" + } + }, + "node_modules/styled-components/node_modules/csstype": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + }, + "node_modules/styled-components/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/styled-components/node_modules/tslib": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" + }, "node_modules/stylehacks": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", @@ -14027,6 +14141,11 @@ "postcss": "^8.2.15" } }, + "node_modules/stylis": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.1.tgz", + "integrity": "sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==" + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", diff --git a/package.json b/package.json index 00f50ade1c..006f259e78 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,8 @@ "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0", "react": "^18.0.0", - "react-dom": "^18.0.0" + "react-dom": "^18.0.0", + "styled-components": "^6.1.8" }, "devDependencies": { "@docusaurus/module-type-aliases": "^3.1.1", @@ -47,4 +48,4 @@ "engines": { "node": ">=18.0" } -} \ No newline at end of file +} diff --git a/src/components/GettingStarted/index.tsx b/src/components/GettingStarted/index.tsx new file mode 100644 index 0000000000..c58d8dcc3a --- /dev/null +++ b/src/components/GettingStarted/index.tsx @@ -0,0 +1,249 @@ +import React, { useRef, useState } from 'react' +import styled from 'styled-components' +// import { defaultTheme } from '../../theme' +// import { Icon } from '../Icon' +// import { Tooltip } from '../tooltip/Tooltip' + +// TODO: consider this https://david-gilbertson.medium.com/icons-as-react-components-de3e33cb8792 + +// TODO: this is filler +const Icon: React.FC<{ icon: string, btn?: string, size?: string }> = ({ icon }) => { + return +} + +// TODO: this is filler +const Tooltip: React.FC> = ({ children }) => { + return <>{children} +} + +// TODO: this is filler +const indigo = { + 100: '#EBF4FF', + 200: '#C3DAFE', + 300: '#A3BFFA', + 400: '#7F9CF5', + 500: '#667EEA', + 600: '#5A67D8', + 700: '#4C51BF', + 800: '#434190', +} + +export const Database = ({ color, width, height }: any) => ( + + + +) + +export const Bolt = ({ color, width, height }: any) => ( + + + +) + +export const SignalStream = ({ color, height, width }: any) => ( + + + +) + +export const BorderBoxWrapper = styled.div<{ border: boolean }>` + padding: 24px 24px 32px 24px; + border-radius: 8px; + background: var(--main-bgd-color); + > * { + font-family: Inter; + text-align: left; + letter-spacing: 0em; + line-height: 20px; + font-size: 14px; + :first-child { + margin-top: 0; + } + :last-child { + margin-bottom: 0; + } + } +` + +export const BoxTitle = styled.h1<{}>` + font-family: Barlow, system-ui, Arial, sans-serif; + font-style: normal; + font-weight: bold; + font-size: 2.5rem !important; + line-height: 48px; + letter-spacing: -0.8px; +` + +export const BorderBox = ({ border, ...props }: any) => ( + {props.children} +) + +const LinkCardWrapper = styled.a` + border: 1px solid var(--border-color); + padding: 20px 24px; + border-radius: 8px; + color: var(--main-font-color); + transition: all 300ms ease-out; + display: flex; + flex-direction: column; + text-decoration: none; + &:hover { + background: var(--main-bgd-color); + border-color: #5a67d8; + } + .title { + display: inline-block; + h6 { + font-size: 18px; + display: inline-block; + margin: 0; + font-family: Barlow; + font-weight: 600; + line-height: 24px; + letter-spacing: 0px; + text-align: left; + } + } + p { + font-family: Inter; + font-size: 14px; + font-weight: 400; + line-height: 20px; + letter-spacing: 0em; + margin-bottom: 0; + text-align: left; + } +` + +export const Grid = styled.div` + gap: 16px; + display: grid; + margin-top: 24px; + grid-template-columns: none; + @media (min-width: 600px) { + grid-template-columns: 1fr 1fr; + } +` + +export const LinkCard = ({ icon, title, desc, link }: any) => { + const linkCardRef = useRef(null) + return ( + +
+ +
{title}
+
+

{desc}

+
+ ) +} + +export const Tab = styled.div` + padding: 15px; + background-color: var(--main-bgd-color); + border: 1px solid ${indigo[600]}; + border-radius: 0px 8px 8px 8px; + font-family: Inter; + font-size: 14px; + font-weight: 400; + line-height: 20px; + letter-spacing: 0em; + text-align: left; + p { + margin-top: 0; + } +` + +const SquareWrapper = styled.a` + width: 90px; + height: 90px; + text-decoration: none; + padding: 22px; + display: inline-block; + border: 1px solid var(--border-color); + background: var(--header-bg-color); + border-radius: 8px; + transition: all 300ms ease-out; + cursor: pointer; + &:hover { + background: var(--main-bgd-color); + border-color: ${indigo[600]}; + } + &:active, + &:focus { + background: var(--code-inline-bgd-color); + border-color: ${indigo[700]}; + } + svg { + width: 100%; + height: 100%; + } +` + +export const SquareLogo = ({ image, tech, url }: any) => { + const squareCardRef = useRef(null) + const [visibleTooltip, setVisibleTooltip] = useState(false) + return ( + <> + setVisibleTooltip(true)} + onMouseLeave={() => setVisibleTooltip(false)} + > + {image} + + {visibleTooltip && ( + + {tech} + + )} + + ) +} + +export const List = styled.div` + display: grid; + gap: 12px; + justify-content: space-between; + grid-template-columns: repeat(3, auto); + @media (min-width: 1240px) { + grid-template-columns: repeat(6, auto); + } + @media (min-width: 1025px) and (max-width: 1240px) { + grid-template-columns: repeat(3, auto); + } + @media (min-width: 768px) and (max-width: 1025px) { + grid-template-columns: repeat(6, auto); + } + @media (min-width: 480px) and (max-width: 768px) { + grid-template-columns: repeat(4, auto); + } +` \ No newline at end of file diff --git a/src/theme/MDXComponents.tsx b/src/theme/MDXComponents.tsx index eb8129d42e..3b62310ab8 100644 --- a/src/theme/MDXComponents.tsx +++ b/src/theme/MDXComponents.tsx @@ -9,38 +9,64 @@ import TabbedContent from '@theme/Tabs'; // Tabs renamed to TabbedContent for ba import TabItem from '@theme/TabItem'; import Link from '@docusaurus/Link'; -// do we want to fix this? +// TODO: do we want to fix this? const TopBlock: React.FC = ({ children }) => { - return

{children}

+ return

{children}

} -// we should fix this +// TODO: we should fix this const CodeWithResult: React.FC<{ children: React.ReactElement[] }> = ({ children }) => { - return <> -

{children[0]}

-

{children[1]}

- + return <> +

{children[0]}

+

{children[1]}

+ } -// we should fix this +// TODO: we should fix this const SwitchTech: React.FC = ({ children }) => { - return

{children}

+ return

{children}

} +// TODO: we should fix this const ParallelBlocks: React.FC = ({ children }) => { - return <>{children} + return <>{children} +} + +type ButtonColor = 'red' | 'green' | 'grey' | 'grey-bg' | 'dark' +interface ButtonProps { + href?: string + target?: string + block?: boolean + color?: ButtonColor + disabled?: boolean + arrow?: boolean + onClick?: any + arrowLeft?: boolean + theme?: any +} + +// TODO: we should fix this +const ButtonLink: React.FC> = ({ children, href }) => { + return {children} +} + +// TODO: we should fix this +const NavigationLinksContainer: React.FC = ({ children }) => { + return <>{children} } export default { - // Re-use the default mapping - ...MDXComponents, - Subsections, - Admonition, - TabbedContent, - TabItem, - Link, - TopBlock, - CodeWithResult, - SwitchTech, - ParallelBlocks, + // Re-use the default mapping + ...MDXComponents, + Subsections, + Admonition, + TabbedContent, + TabItem, + Link, + TopBlock, + CodeWithResult, + SwitchTech, + ParallelBlocks, + ButtonLink, + NavigationLinksContainer, }; \ No newline at end of file diff --git a/static/img/getting-started/1-create-database.jpg b/static/img/getting-started/1-create-database.jpg new file mode 100644 index 0000000000..cbfaab7676 Binary files /dev/null and b/static/img/getting-started/1-create-database.jpg differ diff --git a/static/img/getting-started/2-create-user.jpg b/static/img/getting-started/2-create-user.jpg new file mode 100644 index 0000000000..8a438648d2 Binary files /dev/null and b/static/img/getting-started/2-create-user.jpg differ diff --git a/static/img/getting-started/3-create-posts.jpg b/static/img/getting-started/3-create-posts.jpg new file mode 100644 index 0000000000..2bbbbfa738 Binary files /dev/null and b/static/img/getting-started/3-create-posts.jpg differ diff --git a/static/img/getting-started/prisma-client-install-and-generate.png b/static/img/getting-started/prisma-client-install-and-generate.png new file mode 100644 index 0000000000..af518a72fa Binary files /dev/null and b/static/img/getting-started/prisma-client-install-and-generate.png differ diff --git a/static/img/getting-started/prisma-client-node-module.png b/static/img/getting-started/prisma-client-node-module.png new file mode 100644 index 0000000000..2fc66ee7f5 Binary files /dev/null and b/static/img/getting-started/prisma-client-node-module.png differ diff --git a/static/img/getting-started/prisma-db-pull-generate-schema.png b/static/img/getting-started/prisma-db-pull-generate-schema.png new file mode 100644 index 0000000000..4328184337 Binary files /dev/null and b/static/img/getting-started/prisma-db-pull-generate-schema.png differ diff --git a/static/img/getting-started/prisma-evolve-app-workflow.png b/static/img/getting-started/prisma-evolve-app-workflow.png new file mode 100644 index 0000000000..07030ab64f Binary files /dev/null and b/static/img/getting-started/prisma-evolve-app-workflow.png differ diff --git a/static/img/technologies/cockroachdb.svg b/static/img/technologies/cockroachdb.svg new file mode 100644 index 0000000000..d57cf3ae22 --- /dev/null +++ b/static/img/technologies/cockroachdb.svg @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/static/img/technologies/cockroachdbdark.svg b/static/img/technologies/cockroachdbdark.svg new file mode 100644 index 0000000000..9f223f6e91 --- /dev/null +++ b/static/img/technologies/cockroachdbdark.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/static/img/technologies/cockroachdbgradient.svg b/static/img/technologies/cockroachdbgradient.svg new file mode 100644 index 0000000000..a09d52314c --- /dev/null +++ b/static/img/technologies/cockroachdbgradient.svg @@ -0,0 +1,20 @@ + + + + + + + + + + \ No newline at end of file diff --git a/static/img/technologies/flow.svg b/static/img/technologies/flow.svg new file mode 100644 index 0000000000..bf45c87c65 --- /dev/null +++ b/static/img/technologies/flow.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/static/img/technologies/go.svg b/static/img/technologies/go.svg new file mode 100644 index 0000000000..2e04b15109 --- /dev/null +++ b/static/img/technologies/go.svg @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/static/img/technologies/js.svg b/static/img/technologies/js.svg new file mode 100644 index 0000000000..fb449b8a8f --- /dev/null +++ b/static/img/technologies/js.svg @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/static/img/technologies/mariadb.svg b/static/img/technologies/mariadb.svg new file mode 100644 index 0000000000..6dd2d5bcb6 --- /dev/null +++ b/static/img/technologies/mariadb.svg @@ -0,0 +1,48 @@ + + + + + + + + + + \ No newline at end of file diff --git a/static/img/technologies/mariadbdark.svg b/static/img/technologies/mariadbdark.svg new file mode 100644 index 0000000000..cc5e9791c8 --- /dev/null +++ b/static/img/technologies/mariadbdark.svg @@ -0,0 +1,21 @@ + + + + + + + + + \ No newline at end of file diff --git a/static/img/technologies/mongodb.svg b/static/img/technologies/mongodb.svg new file mode 100644 index 0000000000..69b6564fd8 --- /dev/null +++ b/static/img/technologies/mongodb.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/static/img/technologies/mongodbsimple.svg b/static/img/technologies/mongodbsimple.svg new file mode 100644 index 0000000000..ebe9937d6b --- /dev/null +++ b/static/img/technologies/mongodbsimple.svg @@ -0,0 +1,8 @@ + + + \ No newline at end of file diff --git a/static/img/technologies/mssql.svg b/static/img/technologies/mssql.svg new file mode 100644 index 0000000000..b6b81fb5ec --- /dev/null +++ b/static/img/technologies/mssql.svg @@ -0,0 +1,22 @@ + + + + + + + + + + \ No newline at end of file diff --git a/static/img/technologies/mysql.svg b/static/img/technologies/mysql.svg new file mode 100644 index 0000000000..eef39d31a2 --- /dev/null +++ b/static/img/technologies/mysql.svg @@ -0,0 +1,17 @@ + + + + + \ No newline at end of file diff --git a/static/img/technologies/mysqlsimple.svg b/static/img/technologies/mysqlsimple.svg new file mode 100644 index 0000000000..953749db04 --- /dev/null +++ b/static/img/technologies/mysqlsimple.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/static/img/technologies/nodejs.svg b/static/img/technologies/nodejs.svg new file mode 100644 index 0000000000..b9e45e9d6e --- /dev/null +++ b/static/img/technologies/nodejs.svg @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/static/img/technologies/planetscale.svg b/static/img/technologies/planetscale.svg new file mode 100644 index 0000000000..866cd7adff --- /dev/null +++ b/static/img/technologies/planetscale.svg @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/static/img/technologies/planetscaledark.svg b/static/img/technologies/planetscaledark.svg new file mode 100644 index 0000000000..e91b360fb3 --- /dev/null +++ b/static/img/technologies/planetscaledark.svg @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/static/img/technologies/postgresql.svg b/static/img/technologies/postgresql.svg new file mode 100644 index 0000000000..216d321828 --- /dev/null +++ b/static/img/technologies/postgresql.svg @@ -0,0 +1,42 @@ + + + + + + + + + + \ No newline at end of file diff --git a/static/img/technologies/postgresqldark.svg b/static/img/technologies/postgresqldark.svg new file mode 100644 index 0000000000..120364907e --- /dev/null +++ b/static/img/technologies/postgresqldark.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/static/img/technologies/postgresqlsimple.svg b/static/img/technologies/postgresqlsimple.svg new file mode 100644 index 0000000000..0fa5c685d9 --- /dev/null +++ b/static/img/technologies/postgresqlsimple.svg @@ -0,0 +1,22 @@ + + + + + + + \ No newline at end of file diff --git a/static/img/technologies/sqlite.svg b/static/img/technologies/sqlite.svg new file mode 100644 index 0000000000..8db170a019 --- /dev/null +++ b/static/img/technologies/sqlite.svg @@ -0,0 +1,35 @@ + + + + + + + + + {/* */} + + + + \ No newline at end of file diff --git a/static/img/technologies/sqlserver.svg b/static/img/technologies/sqlserver.svg new file mode 100644 index 0000000000..08651ec5ef --- /dev/null +++ b/static/img/technologies/sqlserver.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/static/img/technologies/typescript.svg b/static/img/technologies/typescript.svg new file mode 100644 index 0000000000..3dc53d6eac --- /dev/null +++ b/static/img/technologies/typescript.svg @@ -0,0 +1,10 @@ + + + + \ No newline at end of file