Synthèse automatique
Guide pour écrire du SQL brut typé avec Prisma Client via $queryRaw, $executeRaw et le tag de template Prisma.sql.
Points forts
- Montre clairement la paramétrisation automatique des templates étiquetés et avertit sur les risques de Prisma.raw() sans liste blanche
- Couvre la composition dynamique de requêtes avec Prisma.sql, Prisma.join et Prisma.empty
- Inclut des requêtes brutes dans des transactions avec verrouillage de lignes, plus une validation des résultats par Zod
- Documente les pièges de typage au retour : noms de colonnes réels, BigInt non sérialisable, Prisma.Decimal, Date
Limites
- Les exemples sont orientés PostgreSQL (ILIKE, LOCK TABLE), non portables tels quels vers d'autres bases
- Ne traite pas la gestion d'erreurs, le benchmark de performance ni le workflow de migration au-delà d'une commande de diff
- Reste succinct sur $queryRawUnsafe, conseillé d'éviter sans détailler les stratégies d'échappement
À utiliser quand une requête Prisma Client ne peut pas exprimer le SQL voulu : CTE, fonctions de fenêtrage, upserts en masse ou fonctionnalités propres à la base.
À éviter quand la requête est exprimable avec l'API typée de Prisma Client, car le SQL brut contourne la génération de types et fait perdre les garanties de sécurité.
Analyse de sécurité
SûrThis is a pure reference/documentation skill for Prisma's raw query APIs. It declares no tools, contains no executable scripts, and makes no network or filesystem calls. The only code shown is illustrative TypeScript that uses parameterized queries and explicitly warns against injection risks with $queryRawUnsafe and Prisma.raw(), recommending allowlist validation of identifiers—guidance that improves rather than degrades safety.
Aucun point d'attention détecté
Comment cette analyse est faiteExemples
Write a Prisma $queryRaw query with a CTE that returns the top 10 users by post count, and validate the rows with Zod.Replace a loop of prisma.post.upsert() with a single $executeRaw using INSERT ... ON CONFLICT to upsert 500 posts at once.Inside a prisma.$transaction, lock the Inventory row for a given SKU with SELECT ... FOR UPDATE and decrement the quantity atomically with $executeRaw.Prisma Raw Queries
Execute type-safe raw SQL with $queryRaw, $executeRaw, and Prisma.sql template tag
When to Use
- Running SQL queries that Prisma Client cannot express (CTEs, window functions, complex joins)
- Performing bulk operations more efficiently than Prisma's generated queries
- Calling database-specific features (full-text search, advisory locks, lateral joins)
- Executing data migrations or one-off scripts
Instructions
- Read query — use
$queryRawwith a tagged template literal. Always parameterize inputs:
const users = await prisma.$queryRaw<User[]>`
SELECT id, email, name FROM "User" WHERE role = ${role}
`;
The template tag automatically parameterizes ${role} as a prepared statement parameter — never string-interpolated.
- Write query — use
$executeRawfor INSERT, UPDATE, DELETE. Returns the affected row count:
const count = await prisma.$executeRaw`
UPDATE "Post" SET "viewCount" = "viewCount" + 1 WHERE id = ${postId}
`;
- Dynamic table or column names — use
Prisma.raw()for identifiers that cannot be parameterized:
import { Prisma } from '@prisma/client';
const column = Prisma.raw(`"${columnName}"`);
const result = await prisma.$queryRaw`
SELECT ${column} FROM "User" WHERE id = ${userId}
`;
Validate columnName against an allowlist before using Prisma.raw() to prevent SQL injection.
- Build dynamic queries with
Prisma.sqlandPrisma.join:
const ids = [1, 2, 3];
const result = await prisma.$queryRaw`
SELECT * FROM "User" WHERE id IN (${Prisma.join(ids)})
`;
- Compose query fragments with
Prisma.sql:
const where = searchTerm ? Prisma.sql`WHERE name ILIKE ${'%' + searchTerm + '%'}` : Prisma.empty;
const users = await prisma.$queryRaw`SELECT * FROM "User" ${where}`;
- Type the result —
$queryRawreturnsunknown[]by default. Pass a generic type or validate with Zod:
import { z } from 'zod';
const UserRow = z.object({ id: z.string(), email: z.string() });
const raw = await prisma.$queryRaw`SELECT id, email FROM "User"`;
const users = z.array(UserRow).parse(raw);
- Use raw queries inside transactions:
await prisma.$transaction(async (tx) => {
await tx.$executeRaw`LOCK TABLE "Inventory" IN EXCLUSIVE MODE`;
const [item] = await tx.$queryRaw<Inventory[]>`
SELECT * FROM "Inventory" WHERE sku = ${sku} FOR UPDATE
`;
await tx.$executeRaw`
UPDATE "Inventory" SET quantity = quantity - ${qty} WHERE sku = ${sku}
`;
});
Details
Raw queries bypass Prisma's query engine and type generation. The SQL runs directly against the database connection, but parameter binding still uses prepared statements for safety.
Table and column naming: Prisma maps model names to table names via @@map and field names to column names via @map. In raw SQL, you must use the actual database names, not the Prisma model names. Check with prisma migrate diff --from-empty --to-schema-datamodel prisma/schema.prisma --script to see the real table names.
Return type caveats:
$queryRawreturns rows with exact database column names (not Prisma field names)BigIntcolumns return JavaScriptBigInt, which is not JSON-serializable — convert toNumberorStringbefore sending to clientsDecimalcolumns returnPrisma.Decimalobjects, notnumberDateTimecolumns returnDateobjects
$queryRawUnsafe / $executeRawUnsafe: Accept a plain string instead of a tagged template. These do NOT parameterize — you are responsible for preventing SQL injection. Avoid unless you are building a query builder that handles parameterization itself.
Performance advantages of raw SQL:
- CTEs and window functions are impossible with Prisma Client but often the most efficient solution
INSERT ... ON CONFLICT(upsert) on multiple rows is significantly faster than loopingprisma.model.upsert()- Bulk updates with CASE expressions are faster than individual
updatecalls
Source
https://prisma.io/docs/orm/prisma-client/queries/raw-database-access
Process
- Read the instructions and examples in this document.
- Apply the patterns to your implementation, adapting to your specific context.
- Verify your implementation against the details and edge cases listed above.
Harness Integration
- Type: knowledge — this skill is a reference document, not a procedural workflow.
- No tools or state — consumed as context by other skills and agents.
Success Criteria
- The patterns described in this document are applied correctly in the implementation.
- Edge cases and anti-patterns listed in this document are avoided.
Du fichier au premier essai
Le téléchargement contient exactement le contenu affiché sur cette fiche. Cette copie peut différer de la dernière version du dépôt source.
Consulter la source et ses fichiers annexesCe téléchargement contient uniquement SKILL.md. Les scripts, références, modèles et dépendances éventuels ne sont pas inclus. Récupérez les fichiers nécessaires depuis la source en conservant leur arborescence avant de poursuivre.
1. Télécharger le fichier
Télécharger SKILL.mdDepuis la racine d’un projet de test, enregistrez le fichier sous .skill-downloads/prisma-raw-queries-ms47vpud/SKILL.md, ou utilisez la commande suivante. Ce dossier sert à examiner la skill avant son installation.
Commande pour macOS/Linux ou WSL : un shell POSIX et curl sont nécessaires. Sous Windows sans WSL, utilisez le bouton de téléchargement et créez le dossier manuellement.
mkdir -p '.skill-downloads/prisma-raw-queries-ms47vpud' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/prisma-raw-queries-ms47vpud/download' --output '.skill-downloads/prisma-raw-queries-ms47vpud/SKILL.md.part' && mv '.skill-downloads/prisma-raw-queries-ms47vpud/SKILL.md.part' '.skill-downloads/prisma-raw-queries-ms47vpud/SKILL.md'2. Vérifier les prérequis
Lisez SKILL.md avant de l’utiliser. Si le fichier cite des scripts ou services externes, examinez-les et préparez les accès nécessaires dans votre environnement de test.
Aucune section de prérequis reconnue dans ce fichier. Cela ne signifie pas qu’il est autonome : les bibliothèques, outils et accès peuvent être cités ailleurs dans le contenu ou dans le dépôt source.
Les plateformes de la fiche sont des indications du catalogue. Les chemins ci-dessous suivent la documentation des outils ; ils ne prouvent pas que cette skill y a été exécutée. Aucune version minimale de ces outils n’est attestée pour cette fiche.
3. Charger la skill
Le fichier ne fournit pas un en-tête name/description exploitable pour cette procédure native. Le téléchargement reste disponible pour lecture ; utilisez le mode manuel ci-dessous.
Mode manuel ou autre outil : joignez SKILL.md à une conversation, ou ouvrez-le dans un agent capable de lire les fichiers. Ajoutez les ressources annexes nécessaires. Il n’existe pas de dossier universel reconnu par tous les outils.
4. Faire un premier essai
Utilisez une entrée courte et fictive : un endpoint d’API, un petit document ou un brief d’interface. Dans une nouvelle conversation, joignez le fichier ou donnez son chemin à l’agent, puis adaptez cette demande :
Lis .skill-downloads/prisma-raw-queries-ms47vpud/SKILL.md et applique ses instructions à cet exemple : [décrire une entrée de test]. Indique les fichiers, dépendances ou accès qui manquent. Produis le résultat demandé par la skill sans inventer de données ni exécuter de script non examiné.Résultat attendu : une sortie correspondant aux instructions de la skill, ou une liste précise des prérequis manquants. Une simple confirmation de lecture ne valide pas le premier usage. Si une ressource externe est indisponible, ce parcours reste à tester.
Bonnes pratiques React Hook Form
Developpement
Maîtrisez React Hook Form : évitez les anti-patterns, gérez les abonnements, et traitez correctement reset, dirty state et entrées contrôlées.
Migration Emotion vers Mantine
Developpement
Migrer les styled-components Emotion vers des composants Mantine avec style props et modules CSS. Pour convertir .styled.tsx ou supprimer les imports @emotion.
Détecteur de dérive de périmètre
Developpement
Analyse les diffs git par rapport à une intention pour détecter la dérive de périmètre, fichiers non liés et PR trop larges, puis suggère de garder, diviser ou justifier.