|
| 1 | +--- |
| 2 | +title: 'Quickstart with Prisma ORM and PlanetScale Postgres' |
| 3 | +sidebar_label: 'PlanetScale Postgres' |
| 4 | +metaTitle: 'Quickstart: Prisma ORM with PlanetScale Postgres (10 min)' |
| 5 | +metaDescription: 'Create a new TypeScript project from scratch by connecting Prisma ORM to PlanetScale Postgres and generating a Prisma Client for database access.' |
| 6 | +--- |
| 7 | + |
| 8 | +import Prerequisites from '../../_components/_prerequisites.mdx' |
| 9 | +import CreateProject from '../../_components/_create-project.mdx' |
| 10 | +import ExploreData from '../../_components/_explore-data.mdx' |
| 11 | +import NextSteps from '../../_components/_next-steps.mdx' |
| 12 | + |
| 13 | +[PlanetScale](https://planetscale.com) is a serverless database platform. This guide covers **PlanetScale Postgres**, a fully managed PostgreSQL database with high availability, branching, and built-in connection pooling. In this guide, you will learn how to set up a new TypeScript project from scratch, connect it to PlanetScale Postgres using Prisma ORM, and generate a Prisma Client for easy, type-safe access to your database. |
| 14 | + |
| 15 | +:::note |
| 16 | + |
| 17 | +PlanetScale also offers MySQL databases (powered by Vitess). If you're using **PlanetScale MySQL**, follow the [PlanetScale MySQL quickstart guide](/getting-started/prisma-orm/quickstart/planetscale) instead. |
| 18 | + |
| 19 | +::: |
| 20 | + |
| 21 | +## Prerequisites |
| 22 | + |
| 23 | +<Prerequisites /> |
| 24 | + |
| 25 | +You also need: |
| 26 | + |
| 27 | +- A [PlanetScale](https://planetscale.com) account |
| 28 | +- A PlanetScale Postgres database |
| 29 | +- Database connection credentials from PlanetScale |
| 30 | + |
| 31 | +## 1. Create a new project |
| 32 | + |
| 33 | +<CreateProject /> |
| 34 | + |
| 35 | +## 2. Install required dependencies |
| 36 | + |
| 37 | +Install the packages needed for this quickstart: |
| 38 | + |
| 39 | +```terminal |
| 40 | +npm install prisma @types/node @types/pg --save-dev |
| 41 | +npm install @prisma/client @prisma/adapter-pg pg dotenv |
| 42 | +``` |
| 43 | + |
| 44 | +Here's what each package does: |
| 45 | + |
| 46 | +- **`prisma`** - The Prisma CLI for running commands like `prisma init`, `prisma migrate`, and `prisma generate` |
| 47 | +- **`@prisma/client`** - The Prisma Client library for querying your database |
| 48 | +- **`@prisma/adapter-pg`** - The [`node-postgres` driver adapter](/orm/overview/databases/postgresql#using-the-node-postgres-driver) that connects Prisma Client to your database |
| 49 | +- **`pg`** - The node-postgres database driver |
| 50 | +- **`@types/pg`** - TypeScript type definitions for node-postgres |
| 51 | +- **`dotenv`** - Loads environment variables from your `.env` file |
| 52 | + |
| 53 | +## 3. Configure ESM support |
| 54 | + |
| 55 | +Update `tsconfig.json` for ESM compatibility: |
| 56 | + |
| 57 | +```json file=tsconfig.json |
| 58 | +{ |
| 59 | + "compilerOptions": { |
| 60 | + "module": "ESNext", |
| 61 | + "moduleResolution": "node", |
| 62 | + "target": "ES2023", |
| 63 | + "strict": true, |
| 64 | + "esModuleInterop": true, |
| 65 | + "ignoreDeprecations": "6.0" |
| 66 | + } |
| 67 | +} |
| 68 | +``` |
| 69 | + |
| 70 | +Update `package.json` to enable ESM: |
| 71 | + |
| 72 | +```json file=package.json |
| 73 | +{ |
| 74 | + // add-start |
| 75 | + "type": "module", |
| 76 | + // add-end |
| 77 | +} |
| 78 | +``` |
| 79 | + |
| 80 | +## 4. Initialize Prisma ORM |
| 81 | + |
| 82 | +You can now invoke the Prisma CLI by prefixing it with `npx`: |
| 83 | + |
| 84 | +```terminal |
| 85 | +npx prisma |
| 86 | +``` |
| 87 | + |
| 88 | +Next, set up your Prisma ORM project by creating your [Prisma Schema](/orm/prisma-schema) file with the following command: |
| 89 | + |
| 90 | +```terminal |
| 91 | +npx prisma init --datasource-provider postgresql --output ../generated/prisma |
| 92 | +``` |
| 93 | + |
| 94 | +This command does a few things: |
| 95 | + |
| 96 | +- Creates a `prisma/` directory with a `schema.prisma` file containing your database connection and schema models |
| 97 | +- Creates a `.env` file in the root directory for environment variables |
| 98 | +- Creates a `prisma.config.ts` file for Prisma configuration |
| 99 | + |
| 100 | +The generated `prisma.config.ts` file looks like this: |
| 101 | + |
| 102 | +```typescript file=prisma.config.ts |
| 103 | +import 'dotenv/config' |
| 104 | +import { defineConfig, env } from 'prisma/config' |
| 105 | + |
| 106 | +export default defineConfig({ |
| 107 | + schema: 'prisma/schema.prisma', |
| 108 | + migrations: { |
| 109 | + path: 'prisma/migrations', |
| 110 | + }, |
| 111 | + datasource: { |
| 112 | + url: env('DATABASE_URL'), |
| 113 | + }, |
| 114 | +}) |
| 115 | +``` |
| 116 | + |
| 117 | +The generated schema uses [the ESM-first `prisma-client` generator](/orm/prisma-schema/overview/generators#prisma-client) with a custom output path: |
| 118 | + |
| 119 | +```prisma file=prisma/schema.prisma |
| 120 | +generator client { |
| 121 | + provider = "prisma-client" |
| 122 | + output = "../generated/prisma" |
| 123 | +} |
| 124 | +
|
| 125 | +datasource db { |
| 126 | + provider = "postgresql" |
| 127 | +} |
| 128 | +``` |
| 129 | + |
| 130 | +## 5. Configure your connection |
| 131 | + |
| 132 | +PlanetScale Postgres offers two connection types: |
| 133 | + |
| 134 | +| Type | Port | Use case | |
| 135 | +|------|------|----------| |
| 136 | +| **Direct** | `5432` | Prisma CLI commands (migrations, introspection), Prisma Studio | |
| 137 | +| **PgBouncer** | `6432` | Application connections, serverless environments | |
| 138 | + |
| 139 | +For production applications, we recommend using PgBouncer for application connections while keeping a direct connection for Prisma CLI commands. |
| 140 | + |
| 141 | +Update your `.env` file with your PlanetScale connection string using the PgBouncer port: |
| 142 | + |
| 143 | +```env file=.env |
| 144 | +DATABASE_URL="postgresql://{username}:{password}@{host}:6432/postgres?sslmode=verify-full" |
| 145 | +``` |
| 146 | + |
| 147 | +Replace the placeholders with your actual PlanetScale credentials from your database dashboard. |
| 148 | + |
| 149 | +The generated `prisma.config.ts` reads the connection string from the environment: |
| 150 | + |
| 151 | +```typescript file=prisma.config.ts |
| 152 | +import 'dotenv/config' |
| 153 | +import { defineConfig, env } from 'prisma/config' |
| 154 | + |
| 155 | +export default defineConfig({ |
| 156 | + schema: 'prisma/schema.prisma', |
| 157 | + migrations: { |
| 158 | + path: 'prisma/migrations', |
| 159 | + }, |
| 160 | + datasource: { |
| 161 | + url: env('DATABASE_URL'), |
| 162 | + }, |
| 163 | +}) |
| 164 | +``` |
| 165 | + |
| 166 | +## 6. Define your data model |
| 167 | + |
| 168 | +Open `prisma/schema.prisma` and add the following models: |
| 169 | + |
| 170 | +```prisma file=prisma/schema.prisma |
| 171 | +generator client { |
| 172 | + provider = "prisma-client" |
| 173 | + output = "../generated/prisma" |
| 174 | +} |
| 175 | +
|
| 176 | +datasource db { |
| 177 | + provider = "postgresql" |
| 178 | +} |
| 179 | +
|
| 180 | +//add-start |
| 181 | +model User { |
| 182 | + id Int @id @default(autoincrement()) |
| 183 | + email String @unique |
| 184 | + name String? |
| 185 | + posts Post[] |
| 186 | +} |
| 187 | +
|
| 188 | +model Post { |
| 189 | + id Int @id @default(autoincrement()) |
| 190 | + title String |
| 191 | + content String? |
| 192 | + published Boolean @default(false) |
| 193 | + author User @relation(fields: [authorId], references: [id]) |
| 194 | + authorId Int |
| 195 | +} |
| 196 | +//add-end |
| 197 | +``` |
| 198 | + |
| 199 | +## 7. Create and apply your first migration |
| 200 | + |
| 201 | +Create your first migration to set up the database tables: |
| 202 | + |
| 203 | +```terminal |
| 204 | +npx prisma migrate dev --name init |
| 205 | +``` |
| 206 | + |
| 207 | +This command creates the database tables based on your schema. |
| 208 | + |
| 209 | +Now run the following command to generate the Prisma Client: |
| 210 | + |
| 211 | +```terminal |
| 212 | +npx prisma generate |
| 213 | +``` |
| 214 | + |
| 215 | +## 8. Instantiate Prisma Client |
| 216 | + |
| 217 | +Now that you have all the dependencies installed, you can instantiate Prisma Client. Pass an instance of Prisma ORM's driver adapter to the `PrismaClient` constructor using the pooled connection: |
| 218 | + |
| 219 | +```typescript file=lib/prisma.ts |
| 220 | +import "dotenv/config"; |
| 221 | +import { PrismaPg } from '@prisma/adapter-pg' |
| 222 | +import { PrismaClient } from '../generated/prisma/client' |
| 223 | + |
| 224 | +const connectionString = `${process.env.DATABASE_URL}` |
| 225 | + |
| 226 | +const adapter = new PrismaPg({ connectionString }) |
| 227 | +const prisma = new PrismaClient({ adapter }) |
| 228 | + |
| 229 | +export { prisma } |
| 230 | +``` |
| 231 | + |
| 232 | +## 9. Write your first query |
| 233 | + |
| 234 | +Create a `script.ts` file to test your setup: |
| 235 | + |
| 236 | +```typescript file=script.ts |
| 237 | +import { prisma } from './lib/prisma' |
| 238 | + |
| 239 | +async function main() { |
| 240 | + // Create a new user with a post |
| 241 | + const user = await prisma.user.create({ |
| 242 | + data: { |
| 243 | + name: 'Alice', |
| 244 | + |
| 245 | + posts: { |
| 246 | + create: { |
| 247 | + title: 'Hello World', |
| 248 | + content: 'This is my first post!', |
| 249 | + published: true, |
| 250 | + }, |
| 251 | + }, |
| 252 | + }, |
| 253 | + include: { |
| 254 | + posts: true, |
| 255 | + }, |
| 256 | + }) |
| 257 | + console.log('Created user:', user) |
| 258 | + |
| 259 | + // Fetch all users with their posts |
| 260 | + const allUsers = await prisma.user.findMany({ |
| 261 | + include: { |
| 262 | + posts: true, |
| 263 | + }, |
| 264 | + }) |
| 265 | + console.log('All users:', JSON.stringify(allUsers, null, 2)) |
| 266 | +} |
| 267 | + |
| 268 | +main() |
| 269 | + .then(async () => { |
| 270 | + await prisma.$disconnect() |
| 271 | + }) |
| 272 | + .catch(async (e) => { |
| 273 | + console.error(e) |
| 274 | + await prisma.$disconnect() |
| 275 | + process.exit(1) |
| 276 | + }) |
| 277 | +``` |
| 278 | + |
| 279 | +Run the script: |
| 280 | + |
| 281 | +```terminal |
| 282 | +npx tsx script.ts |
| 283 | +``` |
| 284 | + |
| 285 | +You should see the created user and all users printed to the console! |
| 286 | + |
| 287 | +## 10. Explore your data with Prisma Studio |
| 288 | + |
| 289 | +<ExploreData /> |
| 290 | + |
| 291 | +## Next steps |
| 292 | + |
| 293 | +<NextSteps /> |
| 294 | + |
| 295 | +## More info |
| 296 | + |
| 297 | +- [PlanetScale Postgres database connector](/orm/overview/databases/planetscale-postgres) |
| 298 | +- [Prisma Config reference](/orm/reference/prisma-config-reference) |
| 299 | +- [Database connection management](/orm/prisma-client/setup-and-configuration/databases-connections) |
| 300 | +- [PlanetScale Postgres documentation](https://planetscale.com/docs/postgres) |
0 commit comments