Upgrade to v1
Comprehensive guide for upgrading from Prisma 1 to Prisma ORM v1
This guide provides a comprehensive roadmap for migrating your project from Prisma 1 to the latest version of Prisma ORM. The migration process involves significant architectural changes and requires careful planning and execution.
Before you begin
- Back up your database before starting the migration
- Review the Prisma ORM documentation to understand the new architecture
- Set up a separate development environment for testing the migration
- Document your current Prisma 1 setup, including models, relations, and any custom configurations
Key changes
Architectural changes
| Feature | Prisma 1 | Prisma ORM |
|---|---|---|
| Database Connection | Uses Prisma Server as a proxy | Direct database connection |
| API | GraphQL API for database | Programmatic access via Prisma Client |
| Schema | GraphQL SDL + prisma.yml | Unified Prisma schema |
| Modeling | GraphQL SDL | Prisma Schema Language (PSL) |
| Workflow | prisma deploy | prisma migrate and prisma db commands |
Feature changes
- Removed: GraphQL API for database
- New: Type-safe database client
- Improved: Database introspection and migration tools
- Enhanced: Support for more database features and types
Migration Strategy
1. Preparation
Install Prisma ORM
# Initialize a new project
npm init -y
npm install prisma @prisma/client
# Initialize Prisma
npx prisma initSet up Database Connection
Update the DATABASE_URL in your .env file to point to your existing database:
DATABASE_URL="postgresql://user:password@localhost:5432/your_database?schema=public"2. Schema Migration
Introspect Database
npx prisma db pullThis will generate a schema.prisma file based on your existing database schema.
Update Schema
After introspection, you'll need to make several adjustments to the schema:
Default Values
// Before (Prisma 1)
model User {
id String @default(cuid())
email String @unique
name String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}Relations
// Before (Prisma 1)
type Post {
id ID! @id
title String!
author User! @relation(name: "UserPosts")
}
// After (Prisma ORM)
model Post {
id Int @id @default(autoincrement())
title String
author User @relation(fields: [authorId], references: [id])
authorId Int
}3. Data Model Adjustments
3.1 Handling Special Types
| Prisma 1 Type | Prisma ORM Equivalent | Notes |
|---|---|---|
ID | String @id @default(cuid()) | Add @id directive |
DateTime | DateTime | No change needed |
Json | Json | No change needed |
Enum | Enum | Define enums in the schema |
3.2 Relation Handling
Prisma ORM requires explicit relation fields and foreign keys:
model User {
id Int @id @default(autoincrement())
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
author User @relation(fields: [authorId], references: [id])
authorId Int
}4. Update Application Code
4.1 Replace Prisma 1 Client with Prisma Client
// Before (Prisma 1)
import { prisma } from './generated/prisma-client';
async function getUser(id: string) {
return prisma.user({ id });
}
// After (Prisma ORM)
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function getUser(id: number) {
return prisma.user.findUnique({
where: { id }
});
}4.2 Update Queries and Mutations
Fetching Data
// Before (Prisma 1)
const user = await prisma.user({ id: 1 });
const posts = await prisma.user({ id: 1 }).posts();
// After (Prisma ORM)
const user = await prisma.user.findUnique({
where: { id: 1 },
include: { posts: true }
});
const posts = user?.posts;Creating Records
// Before (Prisma 1)
const newUser = await prisma.createUser({
name: 'Alice',
email: 'alice@example.com'
});
// After (Prisma ORM)
const newUser = await prisma.user.create({
data: {
name: 'Alice',
email: 'alice@example.com'
}
});Testing and Validation
1. Test Data Operations
Test all CRUD operations to ensure data consistency:
// Test create
const user = await prisma.user.create({
data: { name: 'Test', email: 'test@example.com' }
});
// Test read
const foundUser = await prisma.user.findUnique({
where: { id: user.id }
});
// Test update
const updatedUser = await prisma.user.update({
where: { id: user.id },
data: { name: 'Updated Name' }
});
// Test delete
await prisma.user.delete({
where: { id: user.id }
});2. Test Relations
Verify that all relations work as expected:
// Test relation queries
const userWithPosts = await prisma.user.findUnique({
where: { id: 1 },
include: {
posts: true,
profile: true
}
});
// Test nested writes
const userWithNewPost = await prisma.user.create({
data: {
name: 'Bob',
email: 'bob@example.com',
posts: {
create: {
title: 'Hello World',
content: 'This is my first post'
}
}
},
include: {
posts: true
}
});Handling Special Cases
1. Real-time Subscriptions
Prisma ORM doesn't include built-in real-time subscriptions. Consider these alternatives:
Option 1: Database Triggers
-- PostgreSQL example
CREATE OR REPLACE FUNCTION notify_new_post()
RETURNS TRIGGER AS $$
BEGIN
PERFORM pg_notify('new_post', row_to_json(NEW)::text);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER new_post_trigger
AFTER INSERT ON "Post"
FOR EACH ROW EXECUTE FUNCTION notify_new_post();Option 2: Application-Level Events
// Publish event when creating a post
const post = await prisma.post.create({
data: {
title: 'New Post',
content: 'Content',
author: { connect: { id: userId }}
}
});
// Publish event to your pub/sub system
await pubsub.publish('POST_CREATED', { postCreated: post });2. Authentication
If you were using Prisma 1's built-in authentication, you'll need to implement your own solution:
import { compare } from 'bcryptjs';
import { sign } from 'jsonwebtoken';
export async function login(email: string, password: string) {
const user = await prisma.user.findUnique({ where: { email } });
if (!user) throw new Error('User not found');
const valid = await compare(password, user.password);
if (!valid) throw new Error('Invalid password');
const token = sign({ userId: user.id }, process.env.APP_SECRET!);
return { token, user };
}Migration Tools
Prisma 1 Upgrade CLI
The Prisma 1 Upgrade CLI can help automate parts of the migration:
# Install the upgrade CLI
npm install -g prisma1-upgrade
# Run the upgrade helper
prisma1-upgradeThis tool helps with:
- Converting your Prisma 1 datamodel to Prisma schema
- Identifying potential issues in your schema
- Providing migration recommendations
Performance Considerations
-
Connection Pooling: Configure connection pooling for better performance:
const prisma = new PrismaClient({ log: ['query', 'info', 'warn', 'error'], datasources: { db: { url: process.env.DATABASE_URL + '&connection_limit=20' } } }); -
Query Optimization: Use
selectto fetch only needed fields:const user = await prisma.user.findUnique({ where: { id: 1 }, select: { id: true, name: true, email: true } });
Next Steps
- Prisma ORM Documentation
- Prisma Schema Reference
- Prisma Client API Reference
- Prisma Migrate Guide
- Prisma Studio
Getting Help
If you encounter issues during migration:
- Search the GitHub Issues
- Ask for help in the Prisma Slack
- Open a GitHub Discussion