Isaac.

database

Using Prisma with PostgreSQL

Learn how to use Prisma ORM with PostgreSQL for type-safe database access and migrations.

By Emem IsaacJanuary 14, 20255 min read
#prisma#postgresql#orm#node.js#typescript#database
Share:

A Simple Analogy

Imagine a translator between you and a foreign speaker. You speak English, they speak Spanish, but neither of you speaks the other's language. Prisma is that translator—you write code in JavaScript/TypeScript, and Prisma translates it into SQL that PostgreSQL understands. You never have to write raw SQL; Prisma handles the conversation.


What Is Prisma?

Prisma is an ORM (Object-Relational Mapping) toolkit for Node.js and TypeScript that provides a modern way to access databases. It handles queries, migrations, type safety, and relationships—all with less boilerplate than traditional SQL.


Why Use Prisma with PostgreSQL?

  • Type safety: Full TypeScript support with auto-generated types
  • Simple syntax: Intuitive query API (easier than SQL)
  • Migrations: Easy schema management with auto-generated migration files
  • Relationships: Define one-to-many, many-to-many easily
  • Developer experience: Auto-complete and error checking in your IDE
  • No SQL strings: Never write raw SQL unless you need to

Getting Started with Prisma and PostgreSQL

1. Install Prisma

npm install @prisma/client
npm install -D prisma

2. Initialize Prisma

npx prisma init

This creates .env and prisma/schema.prisma files.

3. Configure Database Connection

.env:

DATABASE_URL="postgresql://user:password@localhost:5432/mydb"

4. Define Your Schema

prisma/schema.prisma:

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  name  String?
  posts Post[]
}

model Post {
  id    Int     @id @default(autoincrement())
  title String
  body  String?
  published Boolean @default(false)
  author User    @relation(fields: [authorId], references: [id])
  authorId Int
}

5. Run Migrations

npx prisma migrate dev --name init

This creates the tables in PostgreSQL and generates the Prisma client.


Querying with Prisma

Create

const newUser = await prisma.user.create({
  data: {
    email: "alice@example.com",
    name: "Alice",
  },
});

Read

// Get one user
const user = await prisma.user.findUnique({
  where: { email: "alice@example.com" },
});

// Get all users
const allUsers = await prisma.user.findMany();

// Get with relations
const userWithPosts = await prisma.user.findUnique({
  where: { id: 1 },
  include: { posts: true },
});

Update

const updated = await prisma.user.update({
  where: { id: 1 },
  data: { name: "Alice Updated" },
});

Delete

const deleted = await prisma.user.delete({
  where: { id: 1 },
});

Relationships

One-to-Many

model Author {
  id    Int     @id @default(autoincrement())
  name  String
  books Book[]
}

model Book {
  id       Int     @id @default(autoincrement())
  title    String
  author   Author  @relation(fields: [authorId], references: [id])
  authorId Int
}

Many-to-Many

model Student {
  id       Int      @id @default(autoincrement())
  name     String
  courses  Course[]
}

model Course {
  id       Int      @id @default(autoincrement())
  name     String
  students Student[]
}

Practical Examples

Blog Application

// Create post with author
const post = await prisma.post.create({
  data: {
    title: "My First Post",
    body: "Content here...",
    author: { connect: { id: 1 } },
  },
});

// Find posts by author
const userPosts = await prisma.post.findMany({
  where: { authorId: 1 },
  include: { author: true },
});

E-commerce Order System

// Create order with items
const order = await prisma.order.create({
  data: {
    userId: 1,
    items: {
      create: [
        { productId: 1, quantity: 2 },
        { productId: 2, quantity: 1 },
      ],
    },
  },
});

// Get order with items
const orderDetail = await prisma.order.findUnique({
  where: { id: 1 },
  include: { items: { include: { product: true } } },
});

Advanced Features

Transactions

const result = await prisma.$transaction([
  prisma.user.update({ where: { id: 1 }, data: { balance: 100 } }),
  prisma.user.update({ where: { id: 2 }, data: { balance: 50 } }),
]);

Raw SQL (When Needed)

const result = await prisma.$queryRaw`
  SELECT * FROM "User" WHERE email = ${email}
`;

Aggregation

const count = await prisma.user.count();

const grouped = await prisma.post.groupBy({
  by: ["authorId"],
  _count: { id: true },
});

Real-World Use Cases

  • E-commerce: Product catalogs, orders, payments
  • Social media: Users, posts, comments, likes
  • SaaS: Multi-tenant apps with user and workspace data
  • Content management: Articles, categories, tags
  • IoT: Device data, sensor readings, logs

Best Practices

  • Use migrations for schema changes (never edit database directly)
  • Keep sensitive data out of .env (use secrets manager in production)
  • Use transactions for multi-step operations
  • Index fields that are frequently queried
  • Use select to only fetch needed columns
  • Implement soft deletes for important data
  • Monitor query performance with Prisma Studio
  • Use prisma studio command to browse data visually

Related Concepts to Explore

  • Entity-Relationship (ER) modeling
  • Database normalization
  • SQL and query optimization
  • Connection pooling
  • Database transactions and ACID
  • GraphQL with Prisma
  • Next.js integration with Prisma
  • TypeORM (alternative ORM)
  • Migration strategies
  • Database monitoring and scaling

Summary

Prisma makes working with PostgreSQL intuitive and type-safe. Instead of writing raw SQL or struggling with manual mapping, you define your schema once and get a powerful, auto-completing query builder. Whether you're building a simple blog or a complex SaaS, Prisma streamlines database access and lets you focus on your application logic.

Share:

Written by Emem Isaac

Expert Software Engineer with 15+ years of experience building scalable enterprise applications. Specialized in ASP.NET Core, Azure, Docker, and modern web development. Passionate about sharing knowledge and helping developers grow.

Ready to Build Something Amazing?

Let's discuss your project and explore how my expertise can help you achieve your goals. Free consultation available.

💼 Trusted by 50+ companies worldwide | ⚡ Average response time: 24 hours