|
| 1 | +# Up and running with Prisma using TypeScript and PostgreSQL |
| 2 | + |
| 3 | +This project follows the Prisma "Getting Started" step-by-step guide for Prisma with PostgreSQL and TypeScript: |
| 4 | + |
| 5 | +https://www.prisma.io/docs/getting-started/setup-prisma/start-from-scratch/relational-databases-typescript-postgres |
| 6 | + |
| 7 | +After you have run these steps you'll gain fundamental knowledge of how Prisma works and better equipped for your first Prisma software project using PostgreSQL and TypeScript. |
| 8 | + |
| 9 | +For this exercice I used Amazon RDS Aurora PostgreSQL with a remote connection to AWS for dev/testing. |
| 10 | + |
| 11 | +This exercise should take around 30 min. |
| 12 | + |
| 13 | +My overall development goal is to create a REST HTTP API deployed to AWS Lambda / API Gateway with Prisma as ORM and PostgreSQL as persistent storage. |
| 14 | + |
| 15 | +## 1. New project setup |
| 16 | + |
| 17 | +Starting from a clean slate: |
| 18 | + |
| 19 | +```sh |
| 20 | +mkdir hello-prisma |
| 21 | +cd hello-prisma |
| 22 | +npm init -y |
| 23 | +npm install prisma typescript ts-node @types/node --save-dev |
| 24 | +``` |
| 25 | + |
| 26 | +Next, create a tsconfig.json file and add the following configuration to it: |
| 27 | + |
| 28 | +```json |
| 29 | +{ |
| 30 | + "compilerOptions": { |
| 31 | + "sourceMap": true, |
| 32 | + "outDir": "dist", |
| 33 | + "strict": true, |
| 34 | + "lib": ["esnext"], |
| 35 | + "esModuleInterop": true |
| 36 | + } |
| 37 | +} |
| 38 | +``` |
| 39 | + |
| 40 | +## 2. Initialise new Prisma project |
| 41 | + |
| 42 | +Next, set up your Prisma project by creating your Prisma schema file with the following command: |
| 43 | + |
| 44 | +```sh |
| 45 | +npx prisma init |
| 46 | +``` |
| 47 | + |
| 48 | +This command does two things: |
| 49 | + |
| 50 | +- 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 |
| 51 | +- Creates the `.env` file in the root directory of the project, which is used for defining environment variables (such as your database connection). |
| 52 | + |
| 53 | +## 3. Connect your database |
| 54 | + |
| 55 | +Add your connection string to `.env` |
| 56 | + |
| 57 | +```sh |
| 58 | +DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public" |
| 59 | +``` |
| 60 | + |
| 61 | +## 4. Using Prisma Migrate |
| 62 | + |
| 63 | +Add the following Prisma data model to your Prisma schema in `/prisma/schema.prisma`: |
| 64 | + |
| 65 | +```js |
| 66 | +model Post { |
| 67 | + id Int @id @default(autoincrement()) |
| 68 | + createdAt DateTime @default(now()) |
| 69 | + updatedAt DateTime @updatedAt |
| 70 | + title String @db.VarChar(255) |
| 71 | + content String? |
| 72 | + published Boolean @default(false) |
| 73 | + author User @relation(fields: [authorId], references: [id]) |
| 74 | + authorId Int |
| 75 | +} |
| 76 | + |
| 77 | +model Profile { |
| 78 | + id Int @id @default(autoincrement()) |
| 79 | + bio String? |
| 80 | + user User @relation(fields: [userId], references: [id]) |
| 81 | + userId Int @unique |
| 82 | +} |
| 83 | + |
| 84 | +model User { |
| 85 | + id Int @id @default(autoincrement()) |
| 86 | + email String @unique |
| 87 | + name String? |
| 88 | + posts Post[] |
| 89 | + profile Profile? |
| 90 | +} |
| 91 | +``` |
| 92 | +
|
| 93 | +To map your data model to the database schema, you need to use the prisma migrate CLI commands: |
| 94 | +
|
| 95 | +```sh |
| 96 | +npx prisma migrate dev --name init |
| 97 | +``` |
| 98 | +
|
| 99 | +This command does two things: |
| 100 | +
|
| 101 | +- It creates a new SQL migration file for this migration |
| 102 | +- It runs the SQL migration file against the database |
| 103 | +
|
| 104 | +> Note: `npx prisma generate` is called under the hood by default, after running `npx 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. |
| 105 | +
|
| 106 | +Great, you now created three tables in your database with Prisma Migrate 🚀 |
| 107 | +
|
| 108 | +https://www.prisma.io/docs/concepts/components/prisma-migrate |
| 109 | +
|
| 110 | +## 5. Install Prisma client |
| 111 | +
|
| 112 | +To get started with Prisma client, you need to install the `@prisma/client` package: |
| 113 | +
|
| 114 | +```sh |
| 115 | +npm install @prisma/client |
| 116 | +``` |
| 117 | +
|
| 118 | +This command does two things: |
| 119 | +
|
| 120 | +- Install a tailor-made client into `/node_modules/.prisma/client/` |
| 121 | +- Invoke the `prisma generate` command under the hood |
| 122 | +
|
| 123 | +> Eveytime you change change the schema or adding models you must run `npx prisma generate` to generate a new Prima client. If you miss step step, the Prisma client will not understand your changes. |
| 124 | +
|
| 125 | +In this context, the Prisma `client` simply refers to the instance used to interact with your PostgreSQL DB e.g |
| 126 | +
|
| 127 | +```js |
| 128 | +import { PrismaClient } from '@prisma/client'; |
| 129 | + |
| 130 | +const prisma = new PrismaClient(); |
| 131 | + |
| 132 | +async function main() { |
| 133 | + const allUsers = await prisma.user.findMany(); |
| 134 | +} |
| 135 | + |
| 136 | +main() |
| 137 | + .catch((e) => { |
| 138 | + throw e; |
| 139 | + }) |
| 140 | + .finally(async () => { |
| 141 | + await prisma.$disconnect(); |
| 142 | + }); |
| 143 | +``` |
| 144 | +
|
| 145 | +## 6. Run |
| 146 | +
|
| 147 | +```sh |
| 148 | +npm run dev |
| 149 | + |
| 150 | +# Equivalent to |
| 151 | +npx ts-node index.ts |
| 152 | +``` |
| 153 | +
|
| 154 | +Should output: |
| 155 | +
|
| 156 | +```json |
| 157 | +[ |
| 158 | + { |
| 159 | + id: 1, |
| 160 | + |
| 161 | + name: 'Alice', |
| 162 | + status: 'unverified', |
| 163 | + posts: [ |
| 164 | + { |
| 165 | + id: 1, |
| 166 | + createdAt: 2022-03-05T09:59:00.755Z, |
| 167 | + updatedAt: 2022-03-05T09:59:00.756Z, |
| 168 | + title: 'Check out Prisma with Next.js', |
| 169 | + content: 'https://www.prisma.io/nextjs', |
| 170 | + published: true, |
| 171 | + authorId: 1 |
| 172 | + } |
| 173 | + ], |
| 174 | + profile: { id: 1, bio: 'I like turtles', userId: 1 } |
| 175 | + }, |
| 176 | + { |
| 177 | + id: 2, |
| 178 | + |
| 179 | + name: 'Bob', |
| 180 | + status: 'unverified', |
| 181 | + posts: [ |
| 182 | + { |
| 183 | + id: 2, |
| 184 | + createdAt: 2022-03-05T09:59:01.053Z, |
| 185 | + updatedAt: 2022-03-05T09:59:01.054Z, |
| 186 | + title: 'Follow Prisma on Twitter', |
| 187 | + content: 'https://twitter.com/prisma', |
| 188 | + published: true, |
| 189 | + authorId: 2 |
| 190 | + }, |
| 191 | + { |
| 192 | + id: 3, |
| 193 | + createdAt: 2022-03-05T09:59:01.053Z, |
| 194 | + updatedAt: 2022-03-05T09:59:01.054Z, |
| 195 | + title: 'Follow Nexus on Twitter', |
| 196 | + content: 'https://twitter.com/nexusgql', |
| 197 | + published: true, |
| 198 | + authorId: 2 |
| 199 | + } |
| 200 | + ], |
| 201 | + profile: null |
| 202 | + } |
| 203 | +] |
| 204 | +``` |
| 205 | +
|
| 206 | +## 7. Important Prisma CLI commands you'll need |
| 207 | +
|
| 208 | +```json |
| 209 | +"scripts": { |
| 210 | + "db:client:generate": "npx prisma generate", |
| 211 | + "db:migrate:dev": "npx prisma migrate dev", |
| 212 | + "db:seed": "npx ts-node prisma/seed.ts", |
| 213 | + "db:migrate:reset": "npx prisma migrate reset", |
| 214 | + "db:reset:migrate:seed": "npm run db:migrate:reset && npm run db:migrate:dev && npm run db:seed" |
| 215 | +} |
| 216 | +``` |
| 217 | +
|
| 218 | +### `npx prisma generate` |
| 219 | +
|
| 220 | +Whenever you make changes to your Prisma schema in the future, you manually need to invoke `npx prisma generate` in order to accommodate the changes in your Prisma Client API. |
| 221 | +
|
| 222 | +### `npx prisma migrate dev` |
| 223 | +
|
| 224 | +Migrates local schema changes to your DB |
| 225 | +
|
| 226 | +### `npx prisma migrate reset` |
| 227 | +
|
| 228 | +Permanently deletes all of your tables and data |
| 229 | +
|
| 230 | +## 8. Seeding your database |
| 231 | +
|
| 232 | +This guide describes how to seed your database using Prisma Client and Prisma's integrated seeding functionality. Seeding allows you to consistently re-create the same data in your database and can be used to: |
| 233 | +
|
| 234 | +- Populate your database with data that is required for your application to start - for example, a default language or a default currency. |
| 235 | +- Provide basic data for validating and using your application in a development environment. This is particularly useful if you are using Prisma Migrate, which sometimes requires resetting your development database. |
| 236 | +
|
| 237 | +Create a seed script in `/prisma/seed.ts`: |
| 238 | +
|
| 239 | +[seed.ts](./prisma/seed.ts) |
| 240 | +
|
| 241 | +Create a new script in `package.json` |
| 242 | +
|
| 243 | +```json |
| 244 | +"scripts": { |
| 245 | + "db:seed": "npx ts-node prisma/seed.ts" |
| 246 | +} |
| 247 | +``` |
| 248 | +
|
| 249 | +Make sure your schema is in sync with your localhost: |
| 250 | +
|
| 251 | +```sh |
| 252 | +npm run db:migrate:dev |
| 253 | + |
| 254 | +# Equivalent to |
| 255 | +npx prisma migrate dev |
| 256 | +``` |
| 257 | +
|
| 258 | +Then, run the seed command |
| 259 | +
|
| 260 | +```sh |
| 261 | +npm run db:seed |
| 262 | +``` |
| 263 | +
|
| 264 | +> Excerpt from https://www.prisma.io/docs/guides/database/seed-database |
| 265 | +
|
| 266 | +# Notes |
| 267 | +
|
| 268 | +## PostgreSQL UI apps |
| 269 | +
|
| 270 | +When testing I tried a few database GUI tools for quick data inspection. |
| 271 | +My goal here, is not to manage the database, but to browse the tables and manipulate the data for dev / testing purposes. |
| 272 | +
|
| 273 | +[PG admin](https://www.pgadmin.org/) |
| 274 | +
|
| 275 | +As the name implies, it's more of a database admin tool, I did not find it particularely useful for quick data access and manipulation without having to write SQL commands and click / brose around in the tree in the left column. |
| 276 | +
|
| 277 | + |
| 278 | +
|
| 279 | +[Postico](https://eggerapps.at/postico/) |
| 280 | +
|
| 281 | +Great app for browsing your tables effortlessly and play around with the data, however it's not free. |
| 282 | +
|
| 283 | + |
| 284 | + |
| 285 | +
|
| 286 | +## Prisma CLI commands |
| 287 | +
|
| 288 | +``` |
| 289 | +Commands |
| 290 | + |
| 291 | + init Setup Prisma for your app |
| 292 | + generate Generate artifacts (e.g. Prisma Client) |
| 293 | + db Manage your database schema and lifecycle |
| 294 | + migrate Migrate your database |
| 295 | + studio Browse your data with Prisma Studio |
| 296 | + format Format your schema |
| 297 | +``` |
| 298 | +
|
| 299 | +``` |
| 300 | +Examples |
| 301 | + |
| 302 | + Setup a new Prisma project |
| 303 | + $ prisma init |
| 304 | + |
| 305 | + Generate artifacts (e.g. Prisma Client) |
| 306 | + $ prisma generate |
| 307 | + |
| 308 | + Browse your data |
| 309 | + $ prisma studio |
| 310 | + |
| 311 | + Create migrations from your Prisma schema, apply them to the database, generate artifacts (e.g. Prisma Client) |
| 312 | + $ prisma migrate dev |
| 313 | + |
| 314 | + Pull the schema from an existing database, updating the Prisma schema |
| 315 | + $ prisma db pull |
| 316 | + |
| 317 | + Push the Prisma schema state to the database |
| 318 | + $ prisma db push |
| 319 | +``` |
0 commit comments