chub-dev 0.1.0 → 0.1.2-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -0
- package/bin/chub-mcp +2 -0
- package/dist/airtable/docs/database/javascript/DOC.md +1437 -0
- package/dist/airtable/docs/database/python/DOC.md +1735 -0
- package/dist/amplitude/docs/analytics/javascript/DOC.md +1282 -0
- package/dist/amplitude/docs/analytics/python/DOC.md +1199 -0
- package/dist/anthropic/docs/claude-api/javascript/DOC.md +503 -0
- package/dist/anthropic/docs/claude-api/python/DOC.md +389 -0
- package/dist/asana/docs/tasks/DOC.md +1396 -0
- package/dist/assemblyai/docs/transcription/DOC.md +1043 -0
- package/dist/atlassian/docs/confluence/javascript/DOC.md +1347 -0
- package/dist/atlassian/docs/confluence/python/DOC.md +1604 -0
- package/dist/auth0/docs/identity/javascript/DOC.md +968 -0
- package/dist/auth0/docs/identity/python/DOC.md +1199 -0
- package/dist/aws/docs/s3/javascript/DOC.md +1773 -0
- package/dist/aws/docs/s3/python/DOC.md +1807 -0
- package/dist/binance/docs/trading/javascript/DOC.md +1315 -0
- package/dist/binance/docs/trading/python/DOC.md +1454 -0
- package/dist/braintree/docs/gateway/javascript/DOC.md +1278 -0
- package/dist/braintree/docs/gateway/python/DOC.md +1179 -0
- package/dist/chromadb/docs/embeddings-db/javascript/DOC.md +1263 -0
- package/dist/chromadb/docs/embeddings-db/python/DOC.md +1707 -0
- package/dist/clerk/docs/auth/javascript/DOC.md +1220 -0
- package/dist/clerk/docs/auth/python/DOC.md +274 -0
- package/dist/cloudflare/docs/workers/javascript/DOC.md +918 -0
- package/dist/cloudflare/docs/workers/python/DOC.md +994 -0
- package/dist/cockroachdb/docs/distributed-db/DOC.md +1500 -0
- package/dist/cohere/docs/llm/DOC.md +1335 -0
- package/dist/datadog/docs/monitoring/javascript/DOC.md +1740 -0
- package/dist/datadog/docs/monitoring/python/DOC.md +1815 -0
- package/dist/deepgram/docs/speech/javascript/DOC.md +885 -0
- package/dist/deepgram/docs/speech/python/DOC.md +685 -0
- package/dist/deepl/docs/translation/javascript/DOC.md +887 -0
- package/dist/deepl/docs/translation/python/DOC.md +944 -0
- package/dist/deepseek/docs/llm/DOC.md +1220 -0
- package/dist/directus/docs/headless-cms/javascript/DOC.md +1128 -0
- package/dist/directus/docs/headless-cms/python/DOC.md +1276 -0
- package/dist/discord/docs/bot/javascript/DOC.md +1090 -0
- package/dist/discord/docs/bot/python/DOC.md +1130 -0
- package/dist/elasticsearch/docs/search/DOC.md +1634 -0
- package/dist/elevenlabs/docs/text-to-speech/javascript/DOC.md +336 -0
- package/dist/elevenlabs/docs/text-to-speech/python/DOC.md +552 -0
- package/dist/firebase/docs/auth/DOC.md +1015 -0
- package/dist/gemini/docs/genai/javascript/DOC.md +691 -0
- package/dist/gemini/docs/genai/python/DOC.md +555 -0
- package/dist/github/docs/octokit/DOC.md +1560 -0
- package/dist/google/docs/bigquery/javascript/DOC.md +1688 -0
- package/dist/google/docs/bigquery/python/DOC.md +1503 -0
- package/dist/hubspot/docs/crm/javascript/DOC.md +1805 -0
- package/dist/hubspot/docs/crm/python/DOC.md +2033 -0
- package/dist/huggingface/docs/transformers/DOC.md +948 -0
- package/dist/intercom/docs/messaging/javascript/DOC.md +1844 -0
- package/dist/intercom/docs/messaging/python/DOC.md +1797 -0
- package/dist/jira/docs/issues/javascript/DOC.md +1420 -0
- package/dist/jira/docs/issues/python/DOC.md +1492 -0
- package/dist/kafka/docs/streaming/javascript/DOC.md +1671 -0
- package/dist/kafka/docs/streaming/python/DOC.md +1464 -0
- package/dist/landingai-ade/docs/api/DOC.md +620 -0
- package/dist/landingai-ade/docs/sdk/python/DOC.md +489 -0
- package/dist/landingai-ade/docs/sdk/typescript/DOC.md +542 -0
- package/dist/landingai-ade/skills/SKILL.md +489 -0
- package/dist/launchdarkly/docs/feature-flags/javascript/DOC.md +1191 -0
- package/dist/launchdarkly/docs/feature-flags/python/DOC.md +1671 -0
- package/dist/linear/docs/tracker/DOC.md +1554 -0
- package/dist/livekit/docs/realtime/javascript/DOC.md +303 -0
- package/dist/livekit/docs/realtime/python/DOC.md +163 -0
- package/dist/mailchimp/docs/marketing/DOC.md +1420 -0
- package/dist/meilisearch/docs/search/DOC.md +1241 -0
- package/dist/microsoft/docs/onedrive/javascript/DOC.md +1421 -0
- package/dist/microsoft/docs/onedrive/python/DOC.md +1549 -0
- package/dist/mongodb/docs/atlas/DOC.md +2041 -0
- package/dist/notion/docs/workspace-api/javascript/DOC.md +1435 -0
- package/dist/notion/docs/workspace-api/python/DOC.md +1400 -0
- package/dist/okta/docs/identity/javascript/DOC.md +1171 -0
- package/dist/okta/docs/identity/python/DOC.md +1401 -0
- package/dist/openai/docs/chat/javascript/DOC.md +407 -0
- package/dist/openai/docs/chat/python/DOC.md +568 -0
- package/dist/paypal/docs/checkout/DOC.md +278 -0
- package/dist/pinecone/docs/sdk/javascript/DOC.md +984 -0
- package/dist/pinecone/docs/sdk/python/DOC.md +1395 -0
- package/dist/plaid/docs/banking/javascript/DOC.md +1163 -0
- package/dist/plaid/docs/banking/python/DOC.md +1203 -0
- package/dist/playwright-community/skills/login-flows/SKILL.md +108 -0
- package/dist/postmark/docs/transactional-email/DOC.md +1168 -0
- package/dist/prisma/docs/orm/javascript/DOC.md +1419 -0
- package/dist/prisma/docs/orm/python/DOC.md +1317 -0
- package/dist/qdrant/docs/vector-search/javascript/DOC.md +1221 -0
- package/dist/qdrant/docs/vector-search/python/DOC.md +1653 -0
- package/dist/rabbitmq/docs/message-queue/javascript/DOC.md +1193 -0
- package/dist/rabbitmq/docs/message-queue/python/DOC.md +1243 -0
- package/dist/razorpay/docs/payments/javascript/DOC.md +1219 -0
- package/dist/razorpay/docs/payments/python/DOC.md +1330 -0
- package/dist/redis/docs/key-value/javascript/DOC.md +1851 -0
- package/dist/redis/docs/key-value/python/DOC.md +2054 -0
- package/dist/registry.json +2817 -0
- package/dist/replicate/docs/model-hosting/DOC.md +1318 -0
- package/dist/resend/docs/email/DOC.md +1271 -0
- package/dist/salesforce/docs/crm/javascript/DOC.md +1241 -0
- package/dist/salesforce/docs/crm/python/DOC.md +1183 -0
- package/dist/search-index.json +1 -0
- package/dist/sendgrid/docs/email-api/javascript/DOC.md +371 -0
- package/dist/sendgrid/docs/email-api/python/DOC.md +656 -0
- package/dist/sentry/docs/error-tracking/javascript/DOC.md +1073 -0
- package/dist/sentry/docs/error-tracking/python/DOC.md +1309 -0
- package/dist/shopify/docs/storefront/DOC.md +457 -0
- package/dist/slack/docs/workspace/javascript/DOC.md +933 -0
- package/dist/slack/docs/workspace/python/DOC.md +271 -0
- package/dist/square/docs/payments/javascript/DOC.md +1855 -0
- package/dist/square/docs/payments/python/DOC.md +1728 -0
- package/dist/stripe/docs/api/DOC.md +1727 -0
- package/dist/stripe/docs/payments/DOC.md +1726 -0
- package/dist/stytch/docs/auth/javascript/DOC.md +1813 -0
- package/dist/stytch/docs/auth/python/DOC.md +1962 -0
- package/dist/supabase/docs/client/DOC.md +1606 -0
- package/dist/twilio/docs/messaging/python/DOC.md +469 -0
- package/dist/twilio/docs/messaging/typescript/DOC.md +946 -0
- package/dist/vercel/docs/platform/DOC.md +1940 -0
- package/dist/weaviate/docs/vector-db/javascript/DOC.md +1268 -0
- package/dist/weaviate/docs/vector-db/python/DOC.md +1388 -0
- package/dist/zendesk/docs/support/javascript/DOC.md +2150 -0
- package/dist/zendesk/docs/support/python/DOC.md +2297 -0
- package/package.json +22 -6
- package/skills/get-api-docs/SKILL.md +84 -0
- package/src/commands/annotate.js +83 -0
- package/src/commands/build.js +12 -1
- package/src/commands/feedback.js +150 -0
- package/src/commands/get.js +83 -42
- package/src/commands/search.js +7 -0
- package/src/index.js +43 -17
- package/src/lib/analytics.js +90 -0
- package/src/lib/annotations.js +57 -0
- package/src/lib/bm25.js +170 -0
- package/src/lib/cache.js +69 -6
- package/src/lib/config.js +8 -3
- package/src/lib/identity.js +99 -0
- package/src/lib/registry.js +103 -20
- package/src/lib/telemetry.js +86 -0
- package/src/mcp/server.js +177 -0
- package/src/mcp/tools.js +251 -0
|
@@ -0,0 +1,1419 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: orm
|
|
3
|
+
description: "Prisma ORM client for JavaScript/TypeScript with type-safe database access and migrations"
|
|
4
|
+
metadata:
|
|
5
|
+
languages: "javascript"
|
|
6
|
+
versions: "6.19.0"
|
|
7
|
+
updated-on: "2026-03-01"
|
|
8
|
+
source: maintainer
|
|
9
|
+
tags: "prisma,orm,database,typescript,migrations"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Prisma ORM - JavaScript/TypeScript
|
|
13
|
+
|
|
14
|
+
## Golden Rule
|
|
15
|
+
|
|
16
|
+
**ALWAYS use `@prisma/client` version 6.19.0+ with the `prisma` CLI for development.**
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @prisma/client@6.19.0
|
|
20
|
+
npm install -D prisma@6.19.0
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**DO NOT** use deprecated packages like:
|
|
24
|
+
- `@prisma/cli` (deprecated - use `prisma` instead)
|
|
25
|
+
- Old Prisma 1.x packages
|
|
26
|
+
- Unofficial Prisma wrappers
|
|
27
|
+
|
|
28
|
+
Prisma ORM is the official next-generation ORM for Node.js and TypeScript. It provides type-safe database access, auto-completion, and an intuitive data modeling experience.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
### Step 1: Install Dependencies
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm install @prisma/client
|
|
38
|
+
npm install -D prisma typescript tsx @types/node
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Step 2: Initialize Prisma
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npx prisma init --datasource-provider postgresql
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
This creates:
|
|
48
|
+
- `prisma/schema.prisma` - Your database schema
|
|
49
|
+
- `.env` - Environment variables file
|
|
50
|
+
|
|
51
|
+
### Step 3: Configure Database Connection
|
|
52
|
+
|
|
53
|
+
Edit `.env`:
|
|
54
|
+
|
|
55
|
+
```env
|
|
56
|
+
DATABASE_URL="postgresql://user:password@localhost:5432/mydb?schema=public"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
For other databases:
|
|
60
|
+
|
|
61
|
+
```env
|
|
62
|
+
# MySQL
|
|
63
|
+
DATABASE_URL="mysql://user:password@localhost:3306/mydb"
|
|
64
|
+
|
|
65
|
+
# SQLite
|
|
66
|
+
DATABASE_URL="file:./dev.db"
|
|
67
|
+
|
|
68
|
+
# MongoDB
|
|
69
|
+
DATABASE_URL="mongodb+srv://user:password@cluster.mongodb.net/mydb"
|
|
70
|
+
|
|
71
|
+
# SQL Server
|
|
72
|
+
DATABASE_URL="sqlserver://localhost:1433;database=mydb;user=sa;password=password;encrypt=true"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Step 4: Initialize TypeScript (if needed)
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npx tsc --init
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Initialization
|
|
84
|
+
|
|
85
|
+
### Basic Client Setup
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import { PrismaClient } from '@prisma/client'
|
|
89
|
+
|
|
90
|
+
const prisma = new PrismaClient()
|
|
91
|
+
|
|
92
|
+
async function main() {
|
|
93
|
+
// Your database queries here
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
main()
|
|
97
|
+
.catch((e) => {
|
|
98
|
+
console.error(e)
|
|
99
|
+
process.exit(1)
|
|
100
|
+
})
|
|
101
|
+
.finally(async () => {
|
|
102
|
+
await prisma.$disconnect()
|
|
103
|
+
})
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Client with Logging
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
import { PrismaClient } from '@prisma/client'
|
|
110
|
+
|
|
111
|
+
const prisma = new PrismaClient({
|
|
112
|
+
log: ['query', 'info', 'warn', 'error'],
|
|
113
|
+
})
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Client with Error Formatting
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
import { PrismaClient } from '@prisma/client'
|
|
120
|
+
|
|
121
|
+
const prisma = new PrismaClient({
|
|
122
|
+
errorFormat: 'pretty', // 'pretty' | 'colorless' | 'minimal'
|
|
123
|
+
})
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Environment-Based Configuration
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
import { PrismaClient } from '@prisma/client'
|
|
130
|
+
|
|
131
|
+
const prisma = new PrismaClient({
|
|
132
|
+
datasources: {
|
|
133
|
+
db: {
|
|
134
|
+
url: process.env.DATABASE_URL,
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
})
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Schema Definition
|
|
143
|
+
|
|
144
|
+
### Basic Schema Structure
|
|
145
|
+
|
|
146
|
+
```prisma
|
|
147
|
+
// prisma/schema.prisma
|
|
148
|
+
|
|
149
|
+
generator client {
|
|
150
|
+
provider = "prisma-client-js"
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
datasource db {
|
|
154
|
+
provider = "postgresql"
|
|
155
|
+
url = env("DATABASE_URL")
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
model User {
|
|
159
|
+
id Int @id @default(autoincrement())
|
|
160
|
+
email String @unique
|
|
161
|
+
name String?
|
|
162
|
+
createdAt DateTime @default(now())
|
|
163
|
+
updatedAt DateTime @updatedAt
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Field Types
|
|
168
|
+
|
|
169
|
+
```prisma
|
|
170
|
+
model Example {
|
|
171
|
+
id Int @id @default(autoincrement())
|
|
172
|
+
string String
|
|
173
|
+
int Int
|
|
174
|
+
bigInt BigInt
|
|
175
|
+
float Float
|
|
176
|
+
decimal Decimal
|
|
177
|
+
boolean Boolean
|
|
178
|
+
dateTime DateTime
|
|
179
|
+
json Json
|
|
180
|
+
bytes Bytes
|
|
181
|
+
optional String?
|
|
182
|
+
array String[]
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Field Attributes
|
|
187
|
+
|
|
188
|
+
```prisma
|
|
189
|
+
model User {
|
|
190
|
+
id Int @id @default(autoincrement())
|
|
191
|
+
uuid String @default(uuid())
|
|
192
|
+
email String @unique
|
|
193
|
+
role String @default("USER")
|
|
194
|
+
createdAt DateTime @default(now())
|
|
195
|
+
updatedAt DateTime @updatedAt
|
|
196
|
+
|
|
197
|
+
@@unique([email, name])
|
|
198
|
+
@@index([email])
|
|
199
|
+
@@map("users")
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Enums
|
|
204
|
+
|
|
205
|
+
```prisma
|
|
206
|
+
enum Role {
|
|
207
|
+
USER
|
|
208
|
+
ADMIN
|
|
209
|
+
MODERATOR
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
model User {
|
|
213
|
+
id Int @id @default(autoincrement())
|
|
214
|
+
role Role @default(USER)
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## Relations
|
|
221
|
+
|
|
222
|
+
### One-to-One
|
|
223
|
+
|
|
224
|
+
```prisma
|
|
225
|
+
model User {
|
|
226
|
+
id Int @id @default(autoincrement())
|
|
227
|
+
email String @unique
|
|
228
|
+
profile Profile?
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
model Profile {
|
|
232
|
+
id Int @id @default(autoincrement())
|
|
233
|
+
bio String
|
|
234
|
+
user User @relation(fields: [userId], references: [id])
|
|
235
|
+
userId Int @unique
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### One-to-Many
|
|
240
|
+
|
|
241
|
+
```prisma
|
|
242
|
+
model User {
|
|
243
|
+
id Int @id @default(autoincrement())
|
|
244
|
+
email String @unique
|
|
245
|
+
posts Post[]
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
model Post {
|
|
249
|
+
id Int @id @default(autoincrement())
|
|
250
|
+
title String
|
|
251
|
+
author User @relation(fields: [authorId], references: [id])
|
|
252
|
+
authorId Int
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Many-to-Many (Implicit)
|
|
257
|
+
|
|
258
|
+
```prisma
|
|
259
|
+
model Post {
|
|
260
|
+
id Int @id @default(autoincrement())
|
|
261
|
+
title String
|
|
262
|
+
categories Category[]
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
model Category {
|
|
266
|
+
id Int @id @default(autoincrement())
|
|
267
|
+
name String
|
|
268
|
+
posts Post[]
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Many-to-Many (Explicit)
|
|
273
|
+
|
|
274
|
+
```prisma
|
|
275
|
+
model Post {
|
|
276
|
+
id Int @id @default(autoincrement())
|
|
277
|
+
title String
|
|
278
|
+
postCategories PostCategory[]
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
model Category {
|
|
282
|
+
id Int @id @default(autoincrement())
|
|
283
|
+
name String
|
|
284
|
+
postCategories PostCategory[]
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
model PostCategory {
|
|
288
|
+
post Post @relation(fields: [postId], references: [id])
|
|
289
|
+
postId Int
|
|
290
|
+
category Category @relation(fields: [categoryId], references: [id])
|
|
291
|
+
categoryId Int
|
|
292
|
+
assignedAt DateTime @default(now())
|
|
293
|
+
|
|
294
|
+
@@id([postId, categoryId])
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Self-Relations
|
|
299
|
+
|
|
300
|
+
```prisma
|
|
301
|
+
model User {
|
|
302
|
+
id Int @id @default(autoincrement())
|
|
303
|
+
name String
|
|
304
|
+
invitedBy User? @relation("UserInvites", fields: [inviterId], references: [id])
|
|
305
|
+
inviterId Int?
|
|
306
|
+
invites User[] @relation("UserInvites")
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## Migrations
|
|
313
|
+
|
|
314
|
+
### Create Migration
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
npx prisma migrate dev --name init
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Apply Migrations in Production
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
npx prisma migrate deploy
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### Reset Database
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
npx prisma migrate reset
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### Generate Client After Schema Changes
|
|
333
|
+
|
|
334
|
+
```bash
|
|
335
|
+
npx prisma generate
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## CRUD Operations
|
|
341
|
+
|
|
342
|
+
### Create
|
|
343
|
+
|
|
344
|
+
#### Single Record
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
const user = await prisma.user.create({
|
|
348
|
+
data: {
|
|
349
|
+
email: 'alice@prisma.io',
|
|
350
|
+
name: 'Alice',
|
|
351
|
+
},
|
|
352
|
+
})
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
#### Multiple Records
|
|
356
|
+
|
|
357
|
+
```typescript
|
|
358
|
+
const users = await prisma.user.createMany({
|
|
359
|
+
data: [
|
|
360
|
+
{ email: 'bob@prisma.io', name: 'Bob' },
|
|
361
|
+
{ email: 'charlie@prisma.io', name: 'Charlie' },
|
|
362
|
+
],
|
|
363
|
+
skipDuplicates: true,
|
|
364
|
+
})
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
#### Create and Return Multiple (v5.14.0+)
|
|
368
|
+
|
|
369
|
+
```typescript
|
|
370
|
+
const users = await prisma.user.createManyAndReturn({
|
|
371
|
+
data: [
|
|
372
|
+
{ email: 'alice@prisma.io', name: 'Alice' },
|
|
373
|
+
{ email: 'bob@prisma.io', name: 'Bob' },
|
|
374
|
+
],
|
|
375
|
+
})
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
#### Create with Relations
|
|
379
|
+
|
|
380
|
+
```typescript
|
|
381
|
+
const user = await prisma.user.create({
|
|
382
|
+
data: {
|
|
383
|
+
email: 'alice@prisma.io',
|
|
384
|
+
name: 'Alice',
|
|
385
|
+
posts: {
|
|
386
|
+
create: [
|
|
387
|
+
{ title: 'First Post' },
|
|
388
|
+
{ title: 'Second Post' },
|
|
389
|
+
],
|
|
390
|
+
},
|
|
391
|
+
},
|
|
392
|
+
})
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
#### Create with Nested Relations
|
|
396
|
+
|
|
397
|
+
```typescript
|
|
398
|
+
const user = await prisma.user.create({
|
|
399
|
+
data: {
|
|
400
|
+
email: 'alice@prisma.io',
|
|
401
|
+
posts: {
|
|
402
|
+
create: {
|
|
403
|
+
title: 'Hello World',
|
|
404
|
+
categories: {
|
|
405
|
+
create: [
|
|
406
|
+
{ name: 'Tech' },
|
|
407
|
+
{ name: 'News' },
|
|
408
|
+
],
|
|
409
|
+
},
|
|
410
|
+
},
|
|
411
|
+
},
|
|
412
|
+
},
|
|
413
|
+
})
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Read
|
|
417
|
+
|
|
418
|
+
#### Find Unique
|
|
419
|
+
|
|
420
|
+
```typescript
|
|
421
|
+
const user = await prisma.user.findUnique({
|
|
422
|
+
where: { email: 'alice@prisma.io' },
|
|
423
|
+
})
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
#### Find Unique or Throw
|
|
427
|
+
|
|
428
|
+
```typescript
|
|
429
|
+
const user = await prisma.user.findUniqueOrThrow({
|
|
430
|
+
where: { id: 1 },
|
|
431
|
+
})
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
#### Find First
|
|
435
|
+
|
|
436
|
+
```typescript
|
|
437
|
+
const user = await prisma.user.findFirst({
|
|
438
|
+
where: {
|
|
439
|
+
posts: {
|
|
440
|
+
some: {
|
|
441
|
+
likes: { gt: 100 },
|
|
442
|
+
},
|
|
443
|
+
},
|
|
444
|
+
},
|
|
445
|
+
orderBy: { id: 'desc' },
|
|
446
|
+
})
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
#### Find First or Throw
|
|
450
|
+
|
|
451
|
+
```typescript
|
|
452
|
+
const user = await prisma.user.findFirstOrThrow({
|
|
453
|
+
where: { email: { contains: 'prisma.io' } },
|
|
454
|
+
})
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
#### Find Many
|
|
458
|
+
|
|
459
|
+
```typescript
|
|
460
|
+
const users = await prisma.user.findMany()
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
#### Find Many with Filter
|
|
464
|
+
|
|
465
|
+
```typescript
|
|
466
|
+
const users = await prisma.user.findMany({
|
|
467
|
+
where: {
|
|
468
|
+
email: { endsWith: 'prisma.io' },
|
|
469
|
+
posts: {
|
|
470
|
+
some: {
|
|
471
|
+
published: true,
|
|
472
|
+
},
|
|
473
|
+
},
|
|
474
|
+
},
|
|
475
|
+
})
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
#### Select Specific Fields
|
|
479
|
+
|
|
480
|
+
```typescript
|
|
481
|
+
const user = await prisma.user.findUnique({
|
|
482
|
+
where: { email: 'alice@prisma.io' },
|
|
483
|
+
select: {
|
|
484
|
+
id: true,
|
|
485
|
+
email: true,
|
|
486
|
+
name: true,
|
|
487
|
+
},
|
|
488
|
+
})
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
#### Include Relations
|
|
492
|
+
|
|
493
|
+
```typescript
|
|
494
|
+
const users = await prisma.user.findMany({
|
|
495
|
+
include: {
|
|
496
|
+
posts: true,
|
|
497
|
+
},
|
|
498
|
+
})
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
#### Include with Nested Relations
|
|
502
|
+
|
|
503
|
+
```typescript
|
|
504
|
+
const users = await prisma.user.findMany({
|
|
505
|
+
include: {
|
|
506
|
+
posts: {
|
|
507
|
+
include: {
|
|
508
|
+
categories: true,
|
|
509
|
+
},
|
|
510
|
+
},
|
|
511
|
+
},
|
|
512
|
+
})
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
#### Include with Filtering
|
|
516
|
+
|
|
517
|
+
```typescript
|
|
518
|
+
const users = await prisma.user.findMany({
|
|
519
|
+
include: {
|
|
520
|
+
posts: {
|
|
521
|
+
where: {
|
|
522
|
+
published: true,
|
|
523
|
+
},
|
|
524
|
+
orderBy: {
|
|
525
|
+
createdAt: 'desc',
|
|
526
|
+
},
|
|
527
|
+
take: 5,
|
|
528
|
+
},
|
|
529
|
+
},
|
|
530
|
+
})
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
### Update
|
|
534
|
+
|
|
535
|
+
#### Update Single Record
|
|
536
|
+
|
|
537
|
+
```typescript
|
|
538
|
+
const user = await prisma.user.update({
|
|
539
|
+
where: { email: 'alice@prisma.io' },
|
|
540
|
+
data: { name: 'Alice Smith' },
|
|
541
|
+
})
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
#### Update Multiple Records
|
|
545
|
+
|
|
546
|
+
```typescript
|
|
547
|
+
const users = await prisma.user.updateMany({
|
|
548
|
+
where: {
|
|
549
|
+
email: { contains: 'prisma.io' },
|
|
550
|
+
},
|
|
551
|
+
data: {
|
|
552
|
+
role: 'ADMIN',
|
|
553
|
+
},
|
|
554
|
+
})
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
#### Update and Return Multiple (v6.2.0+)
|
|
558
|
+
|
|
559
|
+
```typescript
|
|
560
|
+
const users = await prisma.user.updateManyAndReturn({
|
|
561
|
+
where: { email: { contains: 'prisma.io' } },
|
|
562
|
+
data: { role: 'ADMIN' },
|
|
563
|
+
})
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
#### Upsert (Update or Create)
|
|
567
|
+
|
|
568
|
+
```typescript
|
|
569
|
+
const user = await prisma.user.upsert({
|
|
570
|
+
where: { email: 'alice@prisma.io' },
|
|
571
|
+
update: { name: 'Alice Updated' },
|
|
572
|
+
create: {
|
|
573
|
+
email: 'alice@prisma.io',
|
|
574
|
+
name: 'Alice',
|
|
575
|
+
},
|
|
576
|
+
})
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
#### Atomic Number Operations
|
|
580
|
+
|
|
581
|
+
```typescript
|
|
582
|
+
const post = await prisma.post.update({
|
|
583
|
+
where: { id: 1 },
|
|
584
|
+
data: {
|
|
585
|
+
views: { increment: 1 },
|
|
586
|
+
likes: { increment: 5 },
|
|
587
|
+
},
|
|
588
|
+
})
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
```typescript
|
|
592
|
+
const post = await prisma.post.update({
|
|
593
|
+
where: { id: 1 },
|
|
594
|
+
data: {
|
|
595
|
+
views: { decrement: 1 },
|
|
596
|
+
score: { multiply: 2 },
|
|
597
|
+
total: { divide: 10 },
|
|
598
|
+
},
|
|
599
|
+
})
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
#### Update with Relations
|
|
603
|
+
|
|
604
|
+
```typescript
|
|
605
|
+
const user = await prisma.user.update({
|
|
606
|
+
where: { id: 1 },
|
|
607
|
+
data: {
|
|
608
|
+
posts: {
|
|
609
|
+
create: { title: 'New Post' },
|
|
610
|
+
},
|
|
611
|
+
},
|
|
612
|
+
})
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
#### Connect Existing Relations
|
|
616
|
+
|
|
617
|
+
```typescript
|
|
618
|
+
const user = await prisma.user.update({
|
|
619
|
+
where: { id: 1 },
|
|
620
|
+
data: {
|
|
621
|
+
posts: {
|
|
622
|
+
connect: { id: 5 },
|
|
623
|
+
},
|
|
624
|
+
},
|
|
625
|
+
})
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
#### Disconnect Relations
|
|
629
|
+
|
|
630
|
+
```typescript
|
|
631
|
+
const user = await prisma.user.update({
|
|
632
|
+
where: { id: 1 },
|
|
633
|
+
data: {
|
|
634
|
+
posts: {
|
|
635
|
+
disconnect: { id: 5 },
|
|
636
|
+
},
|
|
637
|
+
},
|
|
638
|
+
})
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
### Delete
|
|
642
|
+
|
|
643
|
+
#### Delete Single Record
|
|
644
|
+
|
|
645
|
+
```typescript
|
|
646
|
+
const user = await prisma.user.delete({
|
|
647
|
+
where: { email: 'alice@prisma.io' },
|
|
648
|
+
})
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
#### Delete Multiple Records
|
|
652
|
+
|
|
653
|
+
```typescript
|
|
654
|
+
const users = await prisma.user.deleteMany({
|
|
655
|
+
where: {
|
|
656
|
+
email: { contains: 'prisma.io' },
|
|
657
|
+
},
|
|
658
|
+
})
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
#### Delete All Records
|
|
662
|
+
|
|
663
|
+
```typescript
|
|
664
|
+
const users = await prisma.user.deleteMany({})
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
---
|
|
668
|
+
|
|
669
|
+
## Filtering and Sorting
|
|
670
|
+
|
|
671
|
+
### Basic Filters
|
|
672
|
+
|
|
673
|
+
```typescript
|
|
674
|
+
const users = await prisma.user.findMany({
|
|
675
|
+
where: {
|
|
676
|
+
email: { equals: 'alice@prisma.io' },
|
|
677
|
+
name: { not: 'Bob' },
|
|
678
|
+
age: { gt: 18 },
|
|
679
|
+
},
|
|
680
|
+
})
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
### String Filters
|
|
684
|
+
|
|
685
|
+
```typescript
|
|
686
|
+
const users = await prisma.user.findMany({
|
|
687
|
+
where: {
|
|
688
|
+
email: { startsWith: 'alice' },
|
|
689
|
+
name: { endsWith: 'Smith' },
|
|
690
|
+
bio: { contains: 'developer' },
|
|
691
|
+
},
|
|
692
|
+
})
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
### Number Filters
|
|
696
|
+
|
|
697
|
+
```typescript
|
|
698
|
+
const posts = await prisma.post.findMany({
|
|
699
|
+
where: {
|
|
700
|
+
views: { gt: 100 },
|
|
701
|
+
likes: { gte: 50 },
|
|
702
|
+
comments: { lt: 10 },
|
|
703
|
+
shares: { lte: 5 },
|
|
704
|
+
rating: { in: [4, 5] },
|
|
705
|
+
score: { notIn: [0, 1] },
|
|
706
|
+
},
|
|
707
|
+
})
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
### Logical Operators
|
|
711
|
+
|
|
712
|
+
```typescript
|
|
713
|
+
const users = await prisma.user.findMany({
|
|
714
|
+
where: {
|
|
715
|
+
OR: [
|
|
716
|
+
{ email: { contains: 'prisma.io' } },
|
|
717
|
+
{ name: { contains: 'Alice' } },
|
|
718
|
+
],
|
|
719
|
+
},
|
|
720
|
+
})
|
|
721
|
+
```
|
|
722
|
+
|
|
723
|
+
```typescript
|
|
724
|
+
const users = await prisma.user.findMany({
|
|
725
|
+
where: {
|
|
726
|
+
AND: [
|
|
727
|
+
{ email: { contains: 'prisma.io' } },
|
|
728
|
+
{ role: 'ADMIN' },
|
|
729
|
+
],
|
|
730
|
+
},
|
|
731
|
+
})
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
```typescript
|
|
735
|
+
const users = await prisma.user.findMany({
|
|
736
|
+
where: {
|
|
737
|
+
NOT: {
|
|
738
|
+
email: { contains: 'spam.com' },
|
|
739
|
+
},
|
|
740
|
+
},
|
|
741
|
+
})
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
### Relation Filters
|
|
745
|
+
|
|
746
|
+
```typescript
|
|
747
|
+
const users = await prisma.user.findMany({
|
|
748
|
+
where: {
|
|
749
|
+
posts: {
|
|
750
|
+
some: {
|
|
751
|
+
published: true,
|
|
752
|
+
},
|
|
753
|
+
},
|
|
754
|
+
},
|
|
755
|
+
})
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
```typescript
|
|
759
|
+
const users = await prisma.user.findMany({
|
|
760
|
+
where: {
|
|
761
|
+
posts: {
|
|
762
|
+
every: {
|
|
763
|
+
published: true,
|
|
764
|
+
},
|
|
765
|
+
},
|
|
766
|
+
},
|
|
767
|
+
})
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
```typescript
|
|
771
|
+
const users = await prisma.user.findMany({
|
|
772
|
+
where: {
|
|
773
|
+
posts: {
|
|
774
|
+
none: {
|
|
775
|
+
published: false,
|
|
776
|
+
},
|
|
777
|
+
},
|
|
778
|
+
},
|
|
779
|
+
})
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
### Sorting
|
|
783
|
+
|
|
784
|
+
```typescript
|
|
785
|
+
const users = await prisma.user.findMany({
|
|
786
|
+
orderBy: {
|
|
787
|
+
name: 'asc',
|
|
788
|
+
},
|
|
789
|
+
})
|
|
790
|
+
```
|
|
791
|
+
|
|
792
|
+
```typescript
|
|
793
|
+
const users = await prisma.user.findMany({
|
|
794
|
+
orderBy: [
|
|
795
|
+
{ role: 'desc' },
|
|
796
|
+
{ name: 'asc' },
|
|
797
|
+
],
|
|
798
|
+
})
|
|
799
|
+
```
|
|
800
|
+
|
|
801
|
+
```typescript
|
|
802
|
+
const users = await prisma.user.findMany({
|
|
803
|
+
orderBy: {
|
|
804
|
+
posts: {
|
|
805
|
+
_count: 'desc',
|
|
806
|
+
},
|
|
807
|
+
},
|
|
808
|
+
})
|
|
809
|
+
```
|
|
810
|
+
|
|
811
|
+
---
|
|
812
|
+
|
|
813
|
+
## Pagination
|
|
814
|
+
|
|
815
|
+
### Offset Pagination
|
|
816
|
+
|
|
817
|
+
```typescript
|
|
818
|
+
const users = await prisma.user.findMany({
|
|
819
|
+
skip: 10,
|
|
820
|
+
take: 10,
|
|
821
|
+
})
|
|
822
|
+
```
|
|
823
|
+
|
|
824
|
+
### Cursor-Based Pagination
|
|
825
|
+
|
|
826
|
+
```typescript
|
|
827
|
+
const users = await prisma.user.findMany({
|
|
828
|
+
take: 10,
|
|
829
|
+
cursor: {
|
|
830
|
+
id: lastUserId,
|
|
831
|
+
},
|
|
832
|
+
skip: 1, // Skip cursor itself
|
|
833
|
+
})
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
---
|
|
837
|
+
|
|
838
|
+
## Aggregation
|
|
839
|
+
|
|
840
|
+
### Count
|
|
841
|
+
|
|
842
|
+
```typescript
|
|
843
|
+
const count = await prisma.user.count()
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
```typescript
|
|
847
|
+
const count = await prisma.user.count({
|
|
848
|
+
where: {
|
|
849
|
+
email: { contains: 'prisma.io' },
|
|
850
|
+
},
|
|
851
|
+
})
|
|
852
|
+
```
|
|
853
|
+
|
|
854
|
+
### Aggregate Operations
|
|
855
|
+
|
|
856
|
+
```typescript
|
|
857
|
+
const result = await prisma.post.aggregate({
|
|
858
|
+
_count: {
|
|
859
|
+
_all: true,
|
|
860
|
+
},
|
|
861
|
+
_avg: {
|
|
862
|
+
views: true,
|
|
863
|
+
likes: true,
|
|
864
|
+
},
|
|
865
|
+
_sum: {
|
|
866
|
+
views: true,
|
|
867
|
+
},
|
|
868
|
+
_min: {
|
|
869
|
+
createdAt: true,
|
|
870
|
+
},
|
|
871
|
+
_max: {
|
|
872
|
+
createdAt: true,
|
|
873
|
+
},
|
|
874
|
+
})
|
|
875
|
+
```
|
|
876
|
+
|
|
877
|
+
### Group By
|
|
878
|
+
|
|
879
|
+
```typescript
|
|
880
|
+
const result = await prisma.user.groupBy({
|
|
881
|
+
by: ['role'],
|
|
882
|
+
_count: {
|
|
883
|
+
_all: true,
|
|
884
|
+
},
|
|
885
|
+
})
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
```typescript
|
|
889
|
+
const result = await prisma.user.groupBy({
|
|
890
|
+
by: ['country'],
|
|
891
|
+
_sum: {
|
|
892
|
+
profileViews: true,
|
|
893
|
+
},
|
|
894
|
+
_avg: {
|
|
895
|
+
age: true,
|
|
896
|
+
},
|
|
897
|
+
having: {
|
|
898
|
+
age: {
|
|
899
|
+
_avg: {
|
|
900
|
+
gt: 18,
|
|
901
|
+
},
|
|
902
|
+
},
|
|
903
|
+
},
|
|
904
|
+
})
|
|
905
|
+
```
|
|
906
|
+
|
|
907
|
+
```typescript
|
|
908
|
+
const result = await prisma.post.groupBy({
|
|
909
|
+
by: ['authorId'],
|
|
910
|
+
_count: {
|
|
911
|
+
_all: true,
|
|
912
|
+
},
|
|
913
|
+
orderBy: {
|
|
914
|
+
_count: {
|
|
915
|
+
_all: 'desc',
|
|
916
|
+
},
|
|
917
|
+
},
|
|
918
|
+
})
|
|
919
|
+
```
|
|
920
|
+
|
|
921
|
+
---
|
|
922
|
+
|
|
923
|
+
## Transactions
|
|
924
|
+
|
|
925
|
+
### Sequential Operations Transaction
|
|
926
|
+
|
|
927
|
+
```typescript
|
|
928
|
+
const [deletedPosts, deletedUser] = await prisma.$transaction([
|
|
929
|
+
prisma.post.deleteMany({ where: { authorId: 1 } }),
|
|
930
|
+
prisma.user.delete({ where: { id: 1 } }),
|
|
931
|
+
])
|
|
932
|
+
```
|
|
933
|
+
|
|
934
|
+
### Interactive Transaction
|
|
935
|
+
|
|
936
|
+
```typescript
|
|
937
|
+
const result = await prisma.$transaction(async (tx) => {
|
|
938
|
+
const user = await tx.user.create({
|
|
939
|
+
data: { email: 'alice@prisma.io', name: 'Alice' },
|
|
940
|
+
})
|
|
941
|
+
|
|
942
|
+
const post = await tx.post.create({
|
|
943
|
+
data: {
|
|
944
|
+
title: 'Hello World',
|
|
945
|
+
authorId: user.id,
|
|
946
|
+
},
|
|
947
|
+
})
|
|
948
|
+
|
|
949
|
+
return { user, post }
|
|
950
|
+
})
|
|
951
|
+
```
|
|
952
|
+
|
|
953
|
+
### Transaction with Timeout
|
|
954
|
+
|
|
955
|
+
```typescript
|
|
956
|
+
const result = await prisma.$transaction(
|
|
957
|
+
async (tx) => {
|
|
958
|
+
// Operations here
|
|
959
|
+
},
|
|
960
|
+
{
|
|
961
|
+
maxWait: 5000, // Wait max 5s to start transaction
|
|
962
|
+
timeout: 10000, // Max 10s for transaction
|
|
963
|
+
}
|
|
964
|
+
)
|
|
965
|
+
```
|
|
966
|
+
|
|
967
|
+
### Transaction with Isolation Level
|
|
968
|
+
|
|
969
|
+
```typescript
|
|
970
|
+
const result = await prisma.$transaction(
|
|
971
|
+
async (tx) => {
|
|
972
|
+
// Operations here
|
|
973
|
+
},
|
|
974
|
+
{
|
|
975
|
+
isolationLevel: 'Serializable',
|
|
976
|
+
}
|
|
977
|
+
)
|
|
978
|
+
```
|
|
979
|
+
|
|
980
|
+
---
|
|
981
|
+
|
|
982
|
+
## Raw Queries
|
|
983
|
+
|
|
984
|
+
### Raw Query (Read)
|
|
985
|
+
|
|
986
|
+
```typescript
|
|
987
|
+
import { PrismaClient } from '@prisma/client'
|
|
988
|
+
|
|
989
|
+
const prisma = new PrismaClient()
|
|
990
|
+
|
|
991
|
+
const users = await prisma.$queryRaw`
|
|
992
|
+
SELECT * FROM "User" WHERE "email" = ${'alice@prisma.io'}
|
|
993
|
+
`
|
|
994
|
+
```
|
|
995
|
+
|
|
996
|
+
### Raw Execute (Write)
|
|
997
|
+
|
|
998
|
+
```typescript
|
|
999
|
+
const result = await prisma.$executeRaw`
|
|
1000
|
+
UPDATE "User" SET "name" = ${'Alice'} WHERE "id" = ${1}
|
|
1001
|
+
`
|
|
1002
|
+
```
|
|
1003
|
+
|
|
1004
|
+
### Raw Query Unsafe (Use with Caution)
|
|
1005
|
+
|
|
1006
|
+
```typescript
|
|
1007
|
+
const users = await prisma.$queryRawUnsafe(
|
|
1008
|
+
'SELECT * FROM User WHERE id = ?',
|
|
1009
|
+
1
|
|
1010
|
+
)
|
|
1011
|
+
```
|
|
1012
|
+
|
|
1013
|
+
### Raw Queries in Transactions
|
|
1014
|
+
|
|
1015
|
+
```typescript
|
|
1016
|
+
const [users, count] = await prisma.$transaction([
|
|
1017
|
+
prisma.$queryRaw`SELECT * FROM "User"`,
|
|
1018
|
+
prisma.$executeRaw`UPDATE "User" SET "role" = 'ADMIN' WHERE "id" = ${1}`,
|
|
1019
|
+
])
|
|
1020
|
+
```
|
|
1021
|
+
|
|
1022
|
+
---
|
|
1023
|
+
|
|
1024
|
+
## Advanced Features
|
|
1025
|
+
|
|
1026
|
+
### Distinct
|
|
1027
|
+
|
|
1028
|
+
```typescript
|
|
1029
|
+
const distinctEmails = await prisma.user.findMany({
|
|
1030
|
+
distinct: ['email'],
|
|
1031
|
+
})
|
|
1032
|
+
```
|
|
1033
|
+
|
|
1034
|
+
### Null Filtering
|
|
1035
|
+
|
|
1036
|
+
```typescript
|
|
1037
|
+
const users = await prisma.user.findMany({
|
|
1038
|
+
where: {
|
|
1039
|
+
name: { not: null },
|
|
1040
|
+
},
|
|
1041
|
+
})
|
|
1042
|
+
```
|
|
1043
|
+
|
|
1044
|
+
```typescript
|
|
1045
|
+
const users = await prisma.user.findMany({
|
|
1046
|
+
where: {
|
|
1047
|
+
name: null,
|
|
1048
|
+
},
|
|
1049
|
+
})
|
|
1050
|
+
```
|
|
1051
|
+
|
|
1052
|
+
### Case-Insensitive Filtering (PostgreSQL, MongoDB)
|
|
1053
|
+
|
|
1054
|
+
```typescript
|
|
1055
|
+
const users = await prisma.user.findMany({
|
|
1056
|
+
where: {
|
|
1057
|
+
email: {
|
|
1058
|
+
equals: 'ALICE@PRISMA.IO',
|
|
1059
|
+
mode: 'insensitive',
|
|
1060
|
+
},
|
|
1061
|
+
},
|
|
1062
|
+
})
|
|
1063
|
+
```
|
|
1064
|
+
|
|
1065
|
+
### Full-Text Search (PostgreSQL)
|
|
1066
|
+
|
|
1067
|
+
```typescript
|
|
1068
|
+
const posts = await prisma.post.findMany({
|
|
1069
|
+
where: {
|
|
1070
|
+
title: {
|
|
1071
|
+
search: 'database | prisma',
|
|
1072
|
+
},
|
|
1073
|
+
},
|
|
1074
|
+
})
|
|
1075
|
+
```
|
|
1076
|
+
|
|
1077
|
+
### JSON Filtering
|
|
1078
|
+
|
|
1079
|
+
```typescript
|
|
1080
|
+
const users = await prisma.user.findMany({
|
|
1081
|
+
where: {
|
|
1082
|
+
metadata: {
|
|
1083
|
+
path: ['tags'],
|
|
1084
|
+
array_contains: 'developer',
|
|
1085
|
+
},
|
|
1086
|
+
},
|
|
1087
|
+
})
|
|
1088
|
+
```
|
|
1089
|
+
|
|
1090
|
+
---
|
|
1091
|
+
|
|
1092
|
+
## Client Extensions
|
|
1093
|
+
|
|
1094
|
+
### Custom Result Fields
|
|
1095
|
+
|
|
1096
|
+
```typescript
|
|
1097
|
+
const prisma = new PrismaClient().$extends({
|
|
1098
|
+
result: {
|
|
1099
|
+
user: {
|
|
1100
|
+
fullName: {
|
|
1101
|
+
needs: { firstName: true, lastName: true },
|
|
1102
|
+
compute(user) {
|
|
1103
|
+
return `${user.firstName} ${user.lastName}`
|
|
1104
|
+
},
|
|
1105
|
+
},
|
|
1106
|
+
},
|
|
1107
|
+
},
|
|
1108
|
+
})
|
|
1109
|
+
|
|
1110
|
+
const user = await prisma.user.findUnique({
|
|
1111
|
+
where: { id: 1 },
|
|
1112
|
+
})
|
|
1113
|
+
|
|
1114
|
+
console.log(user.fullName)
|
|
1115
|
+
```
|
|
1116
|
+
|
|
1117
|
+
### Custom Model Methods
|
|
1118
|
+
|
|
1119
|
+
```typescript
|
|
1120
|
+
const prisma = new PrismaClient().$extends({
|
|
1121
|
+
model: {
|
|
1122
|
+
user: {
|
|
1123
|
+
async findByEmail(email: string) {
|
|
1124
|
+
return await prisma.user.findUnique({
|
|
1125
|
+
where: { email },
|
|
1126
|
+
})
|
|
1127
|
+
},
|
|
1128
|
+
},
|
|
1129
|
+
},
|
|
1130
|
+
})
|
|
1131
|
+
|
|
1132
|
+
const user = await prisma.user.findByEmail('alice@prisma.io')
|
|
1133
|
+
```
|
|
1134
|
+
|
|
1135
|
+
### Query Extensions
|
|
1136
|
+
|
|
1137
|
+
```typescript
|
|
1138
|
+
const prisma = new PrismaClient().$extends({
|
|
1139
|
+
query: {
|
|
1140
|
+
user: {
|
|
1141
|
+
async findMany({ args, query }) {
|
|
1142
|
+
console.log('Finding users...')
|
|
1143
|
+
return query(args)
|
|
1144
|
+
},
|
|
1145
|
+
},
|
|
1146
|
+
},
|
|
1147
|
+
})
|
|
1148
|
+
```
|
|
1149
|
+
|
|
1150
|
+
---
|
|
1151
|
+
|
|
1152
|
+
## Middleware
|
|
1153
|
+
|
|
1154
|
+
```typescript
|
|
1155
|
+
const prisma = new PrismaClient()
|
|
1156
|
+
|
|
1157
|
+
prisma.$use(async (params, next) => {
|
|
1158
|
+
const before = Date.now()
|
|
1159
|
+
const result = await next(params)
|
|
1160
|
+
const after = Date.now()
|
|
1161
|
+
|
|
1162
|
+
console.log(`Query ${params.model}.${params.action} took ${after - before}ms`)
|
|
1163
|
+
|
|
1164
|
+
return result
|
|
1165
|
+
})
|
|
1166
|
+
```
|
|
1167
|
+
|
|
1168
|
+
```typescript
|
|
1169
|
+
prisma.$use(async (params, next) => {
|
|
1170
|
+
if (params.model === 'User' && params.action === 'delete') {
|
|
1171
|
+
params.action = 'update'
|
|
1172
|
+
params.args['data'] = { deleted: true }
|
|
1173
|
+
}
|
|
1174
|
+
return next(params)
|
|
1175
|
+
})
|
|
1176
|
+
```
|
|
1177
|
+
|
|
1178
|
+
---
|
|
1179
|
+
|
|
1180
|
+
## Error Handling
|
|
1181
|
+
|
|
1182
|
+
### Handle Specific Errors
|
|
1183
|
+
|
|
1184
|
+
```typescript
|
|
1185
|
+
import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library'
|
|
1186
|
+
|
|
1187
|
+
try {
|
|
1188
|
+
const user = await prisma.user.create({
|
|
1189
|
+
data: { email: 'alice@prisma.io' },
|
|
1190
|
+
})
|
|
1191
|
+
} catch (error) {
|
|
1192
|
+
if (error instanceof PrismaClientKnownRequestError) {
|
|
1193
|
+
if (error.code === 'P2002') {
|
|
1194
|
+
console.log('Unique constraint violation')
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
throw error
|
|
1198
|
+
}
|
|
1199
|
+
```
|
|
1200
|
+
|
|
1201
|
+
### Common Error Codes
|
|
1202
|
+
|
|
1203
|
+
- `P2002`: Unique constraint violation
|
|
1204
|
+
- `P2003`: Foreign key constraint violation
|
|
1205
|
+
- `P2025`: Record not found
|
|
1206
|
+
- `P2014`: Relation violation
|
|
1207
|
+
|
|
1208
|
+
---
|
|
1209
|
+
|
|
1210
|
+
## Database Utilities
|
|
1211
|
+
|
|
1212
|
+
### Connection Test
|
|
1213
|
+
|
|
1214
|
+
```typescript
|
|
1215
|
+
await prisma.$connect()
|
|
1216
|
+
await prisma.$disconnect()
|
|
1217
|
+
```
|
|
1218
|
+
|
|
1219
|
+
### Execute Raw SQL
|
|
1220
|
+
|
|
1221
|
+
```typescript
|
|
1222
|
+
await prisma.$executeRawUnsafe('TRUNCATE TABLE "User" CASCADE')
|
|
1223
|
+
```
|
|
1224
|
+
|
|
1225
|
+
### Run Commands
|
|
1226
|
+
|
|
1227
|
+
```typescript
|
|
1228
|
+
await prisma.$runCommandRaw({
|
|
1229
|
+
drop: 'User',
|
|
1230
|
+
})
|
|
1231
|
+
```
|
|
1232
|
+
|
|
1233
|
+
---
|
|
1234
|
+
|
|
1235
|
+
## Best Patterns for Code Generation
|
|
1236
|
+
|
|
1237
|
+
### Type-Safe Queries
|
|
1238
|
+
|
|
1239
|
+
```typescript
|
|
1240
|
+
import { Prisma } from '@prisma/client'
|
|
1241
|
+
|
|
1242
|
+
const whereClause: Prisma.UserWhereInput = {
|
|
1243
|
+
email: { contains: 'prisma.io' },
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
const users = await prisma.user.findMany({
|
|
1247
|
+
where: whereClause,
|
|
1248
|
+
})
|
|
1249
|
+
```
|
|
1250
|
+
|
|
1251
|
+
### Reusable Query Fragments
|
|
1252
|
+
|
|
1253
|
+
```typescript
|
|
1254
|
+
const userWithPosts = Prisma.validator<Prisma.UserDefaultArgs>()({
|
|
1255
|
+
include: { posts: true },
|
|
1256
|
+
})
|
|
1257
|
+
|
|
1258
|
+
type UserWithPosts = Prisma.UserGetPayload<typeof userWithPosts>
|
|
1259
|
+
|
|
1260
|
+
const user: UserWithPosts = await prisma.user.findUnique({
|
|
1261
|
+
where: { id: 1 },
|
|
1262
|
+
...userWithPosts,
|
|
1263
|
+
})
|
|
1264
|
+
```
|
|
1265
|
+
|
|
1266
|
+
### Type Utilities
|
|
1267
|
+
|
|
1268
|
+
```typescript
|
|
1269
|
+
import { Prisma } from '@prisma/client'
|
|
1270
|
+
|
|
1271
|
+
// Get the type for creating a user
|
|
1272
|
+
type UserCreateInput = Prisma.UserCreateInput
|
|
1273
|
+
|
|
1274
|
+
// Get the type for a user from the database
|
|
1275
|
+
type User = Prisma.UserGetPayload<{}>
|
|
1276
|
+
|
|
1277
|
+
// Get the type for a user with relations
|
|
1278
|
+
type UserWithPosts = Prisma.UserGetPayload<{
|
|
1279
|
+
include: { posts: true }
|
|
1280
|
+
}>
|
|
1281
|
+
```
|
|
1282
|
+
|
|
1283
|
+
---
|
|
1284
|
+
|
|
1285
|
+
## Database-Specific Features
|
|
1286
|
+
|
|
1287
|
+
### PostgreSQL
|
|
1288
|
+
|
|
1289
|
+
```prisma
|
|
1290
|
+
model User {
|
|
1291
|
+
id Int @id @default(autoincrement())
|
|
1292
|
+
data Json @db.JsonB
|
|
1293
|
+
tags String[] @db.VarChar(255)
|
|
1294
|
+
}
|
|
1295
|
+
```
|
|
1296
|
+
|
|
1297
|
+
### MySQL
|
|
1298
|
+
|
|
1299
|
+
```prisma
|
|
1300
|
+
model User {
|
|
1301
|
+
id Int @id @default(autoincrement())
|
|
1302
|
+
name String @db.VarChar(255)
|
|
1303
|
+
bio String @db.Text
|
|
1304
|
+
}
|
|
1305
|
+
```
|
|
1306
|
+
|
|
1307
|
+
### SQLite
|
|
1308
|
+
|
|
1309
|
+
```prisma
|
|
1310
|
+
datasource db {
|
|
1311
|
+
provider = "sqlite"
|
|
1312
|
+
url = "file:./dev.db"
|
|
1313
|
+
}
|
|
1314
|
+
```
|
|
1315
|
+
|
|
1316
|
+
### MongoDB
|
|
1317
|
+
|
|
1318
|
+
```prisma
|
|
1319
|
+
datasource db {
|
|
1320
|
+
provider = "mongodb"
|
|
1321
|
+
url = env("DATABASE_URL")
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
model User {
|
|
1325
|
+
id String @id @default(auto()) @map("_id") @db.ObjectId
|
|
1326
|
+
email String @unique
|
|
1327
|
+
}
|
|
1328
|
+
```
|
|
1329
|
+
|
|
1330
|
+
---
|
|
1331
|
+
|
|
1332
|
+
## Complete Example Application
|
|
1333
|
+
|
|
1334
|
+
```typescript
|
|
1335
|
+
import { PrismaClient } from '@prisma/client'
|
|
1336
|
+
|
|
1337
|
+
const prisma = new PrismaClient()
|
|
1338
|
+
|
|
1339
|
+
async function main() {
|
|
1340
|
+
// Create user with posts
|
|
1341
|
+
const user = await prisma.user.create({
|
|
1342
|
+
data: {
|
|
1343
|
+
email: 'alice@prisma.io',
|
|
1344
|
+
name: 'Alice',
|
|
1345
|
+
posts: {
|
|
1346
|
+
create: [
|
|
1347
|
+
{
|
|
1348
|
+
title: 'Getting Started with Prisma',
|
|
1349
|
+
content: 'Learn how to use Prisma ORM...',
|
|
1350
|
+
published: true,
|
|
1351
|
+
},
|
|
1352
|
+
{
|
|
1353
|
+
title: 'Advanced Prisma Patterns',
|
|
1354
|
+
content: 'Dive deeper into Prisma...',
|
|
1355
|
+
published: false,
|
|
1356
|
+
},
|
|
1357
|
+
],
|
|
1358
|
+
},
|
|
1359
|
+
},
|
|
1360
|
+
include: {
|
|
1361
|
+
posts: true,
|
|
1362
|
+
},
|
|
1363
|
+
})
|
|
1364
|
+
console.log('Created user:', user)
|
|
1365
|
+
|
|
1366
|
+
// Find all published posts with author
|
|
1367
|
+
const publishedPosts = await prisma.post.findMany({
|
|
1368
|
+
where: { published: true },
|
|
1369
|
+
include: { author: true },
|
|
1370
|
+
})
|
|
1371
|
+
console.log('Published posts:', publishedPosts)
|
|
1372
|
+
|
|
1373
|
+
// Update post
|
|
1374
|
+
const updatedPost = await prisma.post.update({
|
|
1375
|
+
where: { id: 1 },
|
|
1376
|
+
data: {
|
|
1377
|
+
views: { increment: 1 },
|
|
1378
|
+
},
|
|
1379
|
+
})
|
|
1380
|
+
console.log('Updated post:', updatedPost)
|
|
1381
|
+
|
|
1382
|
+
// Aggregate data
|
|
1383
|
+
const stats = await prisma.post.aggregate({
|
|
1384
|
+
_count: { _all: true },
|
|
1385
|
+
_avg: { views: true },
|
|
1386
|
+
where: { published: true },
|
|
1387
|
+
})
|
|
1388
|
+
console.log('Post statistics:', stats)
|
|
1389
|
+
|
|
1390
|
+
// Transaction
|
|
1391
|
+
const result = await prisma.$transaction(async (tx) => {
|
|
1392
|
+
const newUser = await tx.user.create({
|
|
1393
|
+
data: {
|
|
1394
|
+
email: 'bob@prisma.io',
|
|
1395
|
+
name: 'Bob',
|
|
1396
|
+
},
|
|
1397
|
+
})
|
|
1398
|
+
|
|
1399
|
+
const newPost = await tx.post.create({
|
|
1400
|
+
data: {
|
|
1401
|
+
title: 'Bob\'s First Post',
|
|
1402
|
+
authorId: newUser.id,
|
|
1403
|
+
},
|
|
1404
|
+
})
|
|
1405
|
+
|
|
1406
|
+
return { user: newUser, post: newPost }
|
|
1407
|
+
})
|
|
1408
|
+
console.log('Transaction result:', result)
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
main()
|
|
1412
|
+
.catch((e) => {
|
|
1413
|
+
console.error(e)
|
|
1414
|
+
process.exit(1)
|
|
1415
|
+
})
|
|
1416
|
+
.finally(async () => {
|
|
1417
|
+
await prisma.$disconnect()
|
|
1418
|
+
})
|
|
1419
|
+
```
|