Développement Prisma ORM dans Cursor : Un Guide Complet

Prisma est un ORM TypeScript de nouvelle génération qui fournit un client de base de données type-safe, des migrations de schéma déclaratives et un navigateur de base de données visuel appelé Prisma Studio. Prisma élimine le code d'accès à la base de données passe-partout et intercepte les erreurs de requête au moment de la compilation. Cursor, avec son assistant IA intégré et sa base compatible VS Code, est un excellent éditeur pour le développement Prisma -- il fournit l'IntelliSense pour le langage de schéma Prisma, l'autocomplétion des requêtes Prisma Client et peut générer des schémas complets à partir de descriptions en langage naturel.
Ce guide couvre le flux de travail complet de développement Prisma dans Cursor : installation et configuration, conception de schéma, migrations, requêtes Prisma Client, relations, Prisma Studio et génération de schéma assistée par IA.
Installation et Configuration de Prisma dans Cursor
Prérequis
Prisma fonctionne avec Node.js 18+ et prend en charge PostgreSQL, MySQL, SQLite, MongoDB et SQL Server. Vérifiez votre version de Node.js :
node --version
Le terminal intégré de Cursor (Ctrl+`) reste synchronisé avec le panneau Explorer. Vous pouvez exécuter des commandes CLI Prisma et voir immédiatement les fichiers générés apparaître dans l'arborescence.
Installation de l'Extension Prisma
Cursor hérite de la compatibilité des extensions VS Code. Installez l'extension officielle Prisma depuis la vue Extensions (Ctrl+Shift+X) :
- Recherchez "Prisma".
- Installez l'extension publiée par Prisma.
- Rechargez Cursor si nécessaire.
L'extension fournit :
- La coloration syntaxique pour les fichiers de schéma
.prisma. - Le formatage automatique à l'enregistrement.
- L'IntelliSense pour les champs de modèle, les attributs et les relations.
- La validation en ligne des erreurs de schéma.
- Des actions de code pour les correctifs rapides.
Si l'extension Prisma n'est pas installée, Cursor traitera les fichiers .prisma comme du texte brut. Vous perdrez la coloration syntaxique, l'autocomplétion et la détection d'erreurs. Installez toujours l'extension officielle avant de modifier les fichiers de schéma.
Initialisation de Prisma dans un Projet
Installez le CLI Prisma et initialisez une nouvelle configuration Prisma :
npm install prisma --save-dev
npm install @prisma/client
npx prisma init
Cela crée :
prisma/schema.prisma-- le fichier de schéma principal..env-- fichier d'environnement avec un placeholderDATABASE_URL.
Définissez votre chaîne de connexion à la base de données dans .env :
# .env
DATABASE_URL="postgresql://user:password@localhost:5432/mydb?schema=public"
Demandez à Cursor : "Configure Prisma avec PostgreSQL dans mon projet. Crée le fichier de schéma avec un modèle User et configure la connexion à la base de données." Cursor exécutera les commandes init, générera le schéma et configurera le fichier .env.
Conception de Schéma
Le schéma Prisma est la source unique de vérité pour votre structure de base de données. Il définit les modèles, les relations, les énumérations et la configuration de la source de données.
Compréhension du Fichier de Schéma
// prisma/schema.prisma
// Generator: tells Prisma how to generate the client
generator client {
provider = "prisma-client-js"
previewFeatures = ["fullTextSearch", "postgresqlExtensions"]
}
// Datasource: database connection
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
extensions = [pgcrypto, postgis]
}
// Model: maps to a database table
model User {
id String @id @default(uuid())
email String @unique
name String?
role Role @default(USER)
posts Post[]
profile Profile?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Post {
id String @id @default(uuid())
title String
content String?
published Boolean @default(false)
viewCount Int @default(0)
author User @relation(fields: [authorId], references: [id])
authorId String
categories Category[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([authorId])
@@index([published])
}
model Category {
id String @id @default(uuid())
name String @unique
posts Post[]
}
model Profile {
id String @id @default(uuid())
bio String?
user User @relation(fields: [userId], references: [id])
userId String @unique
}
enum Role {
USER
ADMIN
EDITOR
}
Attributs de Champ Courants
| Attribut | Description |
|---|---|
@id | Marque un champ comme clé primaire |
@default(uuid()) | Génère automatiquement un UUID à l'insertion |
@default(autoincrement()) | Entier auto-incrémenté (MySQL/PostgreSQL) |
@unique | Applique l'unicité sur le champ |
@updatedAt | Met à jour automatiquement l'horodatage à la mise à jour |
@relation | Définit une relation entre modèles |
@map | Mappe un champ à une colonne de nom différent |
@@index | Crée un index de base de données sur le(s) champ(s) |
@@unique | Contrainte d'unicité composite |
@@map | Mappe un modèle à une table de nom différent |
Demandez à Cursor : "Génère un schéma Prisma pour une plateforme e-commerce avec des modèles User, Product, Order, OrderItem et Category. Inclus les relations appropriées, les index et les énumérations pour le statut de commande et la disponibilité des produits." Cursor produira un schéma complet et validé avec une syntaxe de relation correcte.
Relations
Prisma prend en charge les relations un-à-un, un-à-plusieurs et plusieurs-à-plusieurs.
Un-à-Un :
model User {
id String @id @default(uuid())
profile Profile?
}
model Profile {
id String @id @default(uuid())
user User @relation(fields: [userId], references: [id])
userId String @unique
}
Un-à-Plusieurs :
model User {
id String @id @default(uuid())
posts Post[]
}
model Post {
id String @id @default(uuid())
author User @relation(fields: [authorId], references: [id])
authorId String
}
Plusieurs-à-Plusieurs (implicite) :
model Post {
id String @id @default(uuid())
categories Category[]
}
model Category {
id String @id @default(uuid())
posts Post[]
}
Plusieurs-à-Plusieurs (explicite, avec des champs supplémentaires sur la table de jointure) :
model Post {
id String @id @default(uuid())
tags PostTag[]
}
model Tag {
id String @id @default(uuid())
posts PostTag[]
}
model PostTag {
post Post @relation(fields: [postId], references: [id])
postId String
tag Tag @relation(fields: [tagId], references: [id])
tagId String
assignedAt DateTime @default(now())
@@id([postId, tagId])
}
Lors de l'utilisation de relations plusieurs-à-plusieurs implicites, Prisma génère automatiquement une table de jointure cachée. Vous ne pouvez pas ajouter de champs supplémentaires (comme assignedAt ou createdBy) à cette table cachée. Si vous avez besoin de métadonnées sur la relation, utilisez une table de jointure explicite comme illustré ci-dessus.
Migrations
Prisma Migrate crée et applique des modifications de schéma de base de données de manière versionnée et réversible.
Création de Votre Première Migration
Après avoir défini votre schéma, créez la migration initiale :
npx prisma migrate dev --name init
Cette commande :
- Génère un fichier de migration SQL dans
prisma/migrations/. - Applique la migration à votre base de données.
- Régénère le Prisma Client.
Utilisez des noms de migration descriptifs : npx prisma migrate dev --name add_order_status_enum. Ces noms apparaissent dans l'historique des migrations et vous aident à suivre l'évolution du schéma.
Modification du Schéma
Lorsque vous modifiez le schéma, créez une nouvelle migration :
# After editing schema.prisma
npx prisma migrate dev --name add_post_view_count
Prisma détecte la différence entre votre schéma et la base de données, génère une migration et l'applique.
Flux de Travail de Migration pour la Production
Pour les bases de données de production, utilisez prisma migrate deploy qui applique les migrations en attente sans réinitialiser les données :
# Apply migrations in production
npx prisma migrate deploy
N'exécutez jamais prisma migrate dev sur une base de données de production. La commande dev peut réinitialiser la base de données si elle détecte une dérive de schéma. Utilisez toujours migrate deploy dans les environnements de production.
Réinitialisation de la Base de Données
Pendant le développement, vous pouvez avoir besoin de réinitialiser la base de données et de réappliquer toutes les migrations :
npx prisma migrate reset
Cela supprime toutes les données et tables, puis réapplique toutes les migrations depuis zéro.
Peuplement de la Base de Données
Créez un script de seed pour peupler votre base de données avec des données initiales :
// prisma/seed.ts
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function main() {
// Create users
const alice = await prisma.user.create({
data: {
name: 'Alice Johnson',
role: 'ADMIN',
profile: {
create: {
bio: 'Software engineer and blogger',
},
},
},
});
const bob = await prisma.user.create({
data: {
name: 'Bob Smith',
role: 'USER',
},
});
// Create posts
const post1 = await prisma.post.create({
data: {
title: 'Getting Started with Prisma',
content: 'Prisma is a type-safe ORM...',
published: true,
author: { connect: { id: alice.id } },
},
});
const post2 = await prisma.post.create({
data: {
title: 'Advanced Prisma Relations',
content: 'Relations in Prisma...',
published: true,
author: { connect: { id: alice.id } },
},
});
console.log('Seed data created successfully');
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});
Configurez la commande seed dans package.json :
{
"prisma": {
"seed": "tsx prisma/seed.ts"
}
}
Exécutez le seed :
npx prisma db seed
Demandez à Cursor : "Crée un script de seed pour mon schéma Prisma avec 5 utilisateurs, 20 articles et 10 catégories. Assure-toi que certains articles ne sont pas publiés et que certains utilisateurs ont des profils tandis que d'autres non." Cursor générera un script de seed réaliste qui exerce tous les types de relation.
Requêtes Prisma Client
Prisma Client est le constructeur de requêtes type-safe généré automatiquement qui remplace les modèles ORM traditionnels et le SQL brut.
Instanciation du Client
Créez une instance singleton pour éviter des connexions multiples en développement :
// lib/prisma.ts
import { PrismaClient } from '@prisma/client';
const globalForPrisma = globalThis as unknown as {
prisma: PrismaClient | undefined;
};
export const prisma =
globalForPrisma.prisma ??
new PrismaClient({
log: ['query', 'info', 'warn', 'error'],
});
if (process.env.NODE_ENV !== 'production') {
globalForPrisma.prisma = prisma;
}
En développement avec rechargement de module à chaud, la création d'un nouveau PrismaClient à chaque changement de fichier provoque l'épuisement du pool de connexions. Le modèle singleton ci-dessus évite cela en mettant en cache l'instance sur globalThis.
Opérations CRUD
Créer :
// Create a single record
const user = await prisma.user.create({
data: {
name: 'Charlie Brown',
profile: {
create: {
bio: 'New user bio',
},
},
},
});
// Create multiple records
const users = await prisma.user.createMany({
data: [
],
});
Lire :
// Find a single record
const user = await prisma.user.findUnique({
include: { profile: true, posts: true },
});
// Find multiple records with filtering and sorting
const publishedPosts = await prisma.post.findMany({
where: { published: true },
orderBy: { createdAt: 'desc' },
take: 10,
skip: 0,
include: {
author: {
select: { id: true, name: true, email: true },
},
},
});
// Count records
const totalPosts = await prisma.post.count({
where: { published: true },
});
Mettre à jour :
// Update a single record
const updatedPost = await prisma.post.update({
where: { id: postId },
data: {
title: 'Updated Title',
viewCount: { increment: 1 },
},
});
// Update multiple records
const result = await prisma.post.updateMany({
where: { published: false, authorId: userId },
data: { published: true },
});
Supprimer :
// Delete a single record
const deletedUser = await prisma.user.delete({
where: { id: userId },
});
// Delete multiple records
const result = await prisma.post.deleteMany({
where: { authorId: userId, published: false },
});
Filtrage Avancé
const posts = await prisma.post.findMany({
where: {
AND: [
{ published: true },
{
OR: [
{ title: { contains: 'prisma', mode: 'insensitive' } },
{ content: { contains: 'orm', mode: 'insensitive' } },
],
},
],
createdAt: {
gte: new Date('2024-01-01'),
lte: new Date('2024-12-31'),
},
author: {
role: { in: ['ADMIN', 'EDITOR'] },
},
},
orderBy: [{ viewCount: 'desc' }, { createdAt: 'desc' }],
});
Transactions
// Interactive transaction
const result = await prisma.$transaction(async (tx) => {
const author = await tx.user.create({
});
const post = await tx.post.create({
data: {
title: 'My First Post',
content: 'Hello world',
authorId: author.id,
},
});
await tx.profile.create({
data: {
bio: 'New author profile',
userId: author.id,
},
});
return { author, post };
});
Demandez à Cursor : "Écris une transaction Prisma qui transfère des crédits entre deux utilisateurs. Déduis de l'expéditeur, ajoute au destinataire et crée un enregistrement de transfert. Annule si l'expéditeur a un solde insuffisant." Cursor générera la transaction interactive avec une gestion d'erreurs appropriée.
Pagination
// Offset-based pagination
const page = 1;
const pageSize = 10;
const [posts, totalCount] = await prisma.$transaction([
prisma.post.findMany({
where: { published: true },
orderBy: { createdAt: 'desc' },
skip: (page - 1) * pageSize,
take: pageSize,
include: { author: true },
}),
prisma.post.count({ where: { published: true } }),
]);
const totalPages = Math.ceil(totalCount / pageSize);
Prisma Studio
Prisma Studio est un navigateur de base de données visuel qui s'exécute dans votre navigateur. Il vous permet de visualiser, créer, mettre à jour et supprimer des enregistrements sans écrire de requêtes.
Lancement de Prisma Studio
npx prisma studio
Cela ouvre une interface navigateur à http://localhost:5555 où vous pouvez :
- Parcourir tous les modèles définis dans votre schéma.
- Visualiser les enregistrements dans un tableau triable et filtrable.
- Créer de nouveaux enregistrements avec une interface de formulaire.
- Éditer les enregistrements existants en cliquant sur les cellules.
- Supprimer des enregistrements avec une boîte de dialogue de confirmation.
- Filtrer et rechercher des enregistrements par valeurs de champ.
Prisma Studio est inestimable pour le débogage pendant le développement. Au lieu d'écrire des requêtes jetables, lancez Studio, inspectez vos données et faites des modifications rapides. Il reflète les changements en temps réel.
Prisma Studio écrit directement dans votre base de données. Soyez prudent lorsque vous l'utilisez sur une base de données de production -- il n'y a pas d'annulation pour les suppressions ou les modifications. Sauvegardez toujours vos données avant d'effectuer des modifications manuelles dans Studio.
Filtrage dans Studio
Prisma Studio prend en charge le filtrage par :
- Nom de champ (sélectionnez n'importe quelle colonne).
- Opérateur de filtre (égal à, différent de, contient, commence par, se termine par, etc.).
- Plusieurs filtres combinés avec la logique AND/OR.