Prisma ORM - Type-Safe Database Operations

VerifiedSafe

Prisma ORM for type-safe database operations with PostgreSQL. Enables declarative schema modeling, automatic type generation, and migration management.

Sby Skills Guide Bot
DevelopmentIntermediate
306/2/2026
Claude Code
#prisma#orm#postgresql#type-safety#database-migrations

Recommended for

Our review

This skill enables using Prisma ORM for type-safe database operations with PostgreSQL, replacing raw SQL queries with declarative schemas and automated migrations.

Strengths

  • Automatic TypeScript type generation from the schema, reducing mapping errors
  • Simplified migration management and relation modeling
  • Optimized queries with support for joins, transactions, and advanced filtering

Limitations

  • Learning curve for developers accustomed to raw SQL
  • May generate less performant queries than finely tuned SQL
  • Adds a dependency to the tech stack
When to use it

Ideal for projects needing a solid abstraction layer with strong typing and easy migration handling.

When not to use it

Avoid if the team is highly proficient in SQL and the database has very complex, performance-critical queries.

Security analysis

Safe
Quality score90/100

The skill uses Bash only for legitimate Prisma CLI commands (npm install, npx prisma init) and no destructive or exfiltrating operations are present.

No concerns found

Examples

Localized product fetch with fallback
Using Prisma in our backend, write a query that fetches a product by ID and includes its translation for a given language code. If no translation exists, fall back to the base product's name and description.
Create order with transaction
Write a Prisma transaction that creates an order with order items, decrements product inventory, and handles concurrency safely. Assume models Order, OrderItem, and Product exist with appropriate relations.
Initialize Prisma for existing PostgreSQL database
Our Node.js backend uses raw SQL with the 'pg' library. Help me set up Prisma: install dependencies, initialize Prisma, introspect the existing PostgreSQL schema, and generate the Prisma client. Then show me how to replace a raw SQL query with a Prisma query.

name: prisma description: | Prisma ORM for type-safe database operations with PostgreSQL. Use when: Defining schemas, writing type-safe queries, creating migrations, modeling relations, or replacing raw SQL with ORM patterns. allowed-tools: Read, Edit, Write, Glob, Grep, Bash

Prisma Skill

Provides type-safe database operations as an alternative to raw SQL. This codebase currently uses the pg library with raw SQL queries. Prisma offers automatic type generation, declarative schema modeling, and migration management - eliminating the manual row mapping and SQL injection risks present in raw SQL approaches.

Quick Start

Install and Initialize

cd backend
npm install prisma @prisma/client
npx prisma init

Schema Definition

// prisma/schema.prisma
generator client {
  provider = "prisma-client-js"
}

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

model Product {
  id               Int                    @id @default(autoincrement())
  name             String
  shortDescription String                 @map("short_description")
  description      String
  price            Decimal                @db.Decimal(10, 2)
  salePrice        Decimal?               @map("sale_price") @db.Decimal(10, 2)
  imageUrl         String                 @map("image_url")
  inventory        Int                    @default(0)
  categories       Json
  highlights       Json?
  usage            String?
  isNew            Boolean                @default(false) @map("is_new")
  isFeatured       Boolean                @default(false) @map("is_featured")
  salesCount       Int                    @default(0) @map("sales_count")
  createdAt        DateTime               @default(now()) @map("created_at")
  updatedAt        DateTime               @updatedAt @map("updated_at")
  translations     ProductTranslation[]
  orderItems       OrderItem[]
  variants         ProductVariant[]

  @@map("products")
}

model ProductTranslation {
  id              Int      @id @default(autoincrement())
  productId       Int      @map("product_id")
  languageCode    String   @map("language_code") @db.VarChar(10)
  name            String   @db.VarChar(255)
  shortDescription String  @map("short_description")
  description     String
  highlights      Json?
  usage           String?
  slug            String?  @db.VarChar(255)
  createdAt       DateTime @default(now()) @map("created_at")
  updatedAt       DateTime @updatedAt @map("updated_at")
  product         Product  @relation(fields: [productId], references: [id], onDelete: Cascade)
  language        Language @relation(fields: [languageCode], references: [code], onDelete: Cascade)

  @@unique([productId, languageCode])
  @@map("product_translations")
}

Client Usage

// backend/src/db/prisma.ts
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient({
  log: process.env.NODE_ENV === 'development' ? ['query', 'warn', 'error'] : ['error'],
});

export { prisma };

Key Concepts

| Concept | Usage | Example | |---------|-------|---------| | @map | Map field to snake_case column | @map("created_at") | | @@map | Map model to table name | @@map("products") | | Relations | Define FK relationships | product Product @relation(...) | | @db.Decimal | Specify PostgreSQL types | @db.Decimal(10, 2) | | @@unique | Composite unique constraints | @@unique([productId, languageCode]) | | Transactions | Atomic operations | prisma.$transaction([...]) |

Common Patterns

Fetching with Translation Fallback

When: Getting localized content with English fallback

const product = await prisma.product.findUnique({
  where: { id: productId },
  include: {
    translations: {
      where: { languageCode: lang },
    },
  },
});

// Apply translation or fallback to base
const name = product.translations[0]?.name ?? product.name;

Transactions for Orders

When: Creating orders with inventory updates

await prisma.$transaction(async (tx) => {
  const order = await tx.order.create({ data: orderData });
  
  for (const item of items) {
    await tx.orderItem.create({
      data: { orderId: order.id, ...item },
    });
    await tx.product.update({
      where: { id: item.productId },
      data: { inventory: { decrement: item.quantity } },
    });
  }
  
  return order;
});

See Also

  • patterns - Query patterns and model design
  • workflows - Migrations and schema management

Related Skills

  • See the postgresql skill for raw SQL patterns and PostgreSQL-specific features
  • See the typescript skill for type inference patterns with Prisma
  • See the zod skill for runtime validation of Prisma inputs
Related skills