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,1317 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: orm
|
|
3
|
+
description: "Prisma Client Python for type-safe database access and schema-driven development"
|
|
4
|
+
metadata:
|
|
5
|
+
languages: "python"
|
|
6
|
+
versions: "0.15.0"
|
|
7
|
+
updated-on: "2026-03-01"
|
|
8
|
+
source: maintainer
|
|
9
|
+
tags: "prisma,orm,database,python,migrations"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Prisma Client Python
|
|
13
|
+
|
|
14
|
+
## Golden Rule
|
|
15
|
+
|
|
16
|
+
**ALWAYS use `prisma` (prisma-client-py) version 0.15.0+ for Python projects.**
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install prisma==0.15.0
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**IMPORTANT NOTE:** Prisma Client Python is no longer actively maintained as of April 2025. However, version 0.15.0 remains functional and is documented here for existing projects.
|
|
23
|
+
|
|
24
|
+
**DO NOT** use:
|
|
25
|
+
- Old `prisma2` packages
|
|
26
|
+
- Unofficial Prisma Python wrappers
|
|
27
|
+
- `prisma-client` (different package on PyPI)
|
|
28
|
+
|
|
29
|
+
Prisma Client Python is an auto-generated, fully type-safe database client designed for ease of use with Python applications. It provides intuitive data modeling, automated migrations, and comprehensive type safety.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
### Step 1: Install Prisma
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install prisma
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Step 2: Create Schema File
|
|
42
|
+
|
|
43
|
+
Create `schema.prisma` in your project root:
|
|
44
|
+
|
|
45
|
+
```prisma
|
|
46
|
+
datasource db {
|
|
47
|
+
provider = "postgresql"
|
|
48
|
+
url = env("DATABASE_URL")
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
generator client {
|
|
52
|
+
provider = "prisma-client-py"
|
|
53
|
+
recursive_type_depth = 5
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
model User {
|
|
57
|
+
id Int @id @default(autoincrement())
|
|
58
|
+
email String @unique
|
|
59
|
+
name String?
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Step 3: Set Environment Variable
|
|
64
|
+
|
|
65
|
+
Create `.env` file:
|
|
66
|
+
|
|
67
|
+
```env
|
|
68
|
+
DATABASE_URL="postgresql://user:password@localhost:5432/mydb?schema=public"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
For other databases:
|
|
72
|
+
|
|
73
|
+
```env
|
|
74
|
+
# MySQL
|
|
75
|
+
DATABASE_URL="mysql://user:password@localhost:3306/mydb"
|
|
76
|
+
|
|
77
|
+
# SQLite
|
|
78
|
+
DATABASE_URL="file:./dev.db"
|
|
79
|
+
|
|
80
|
+
# MongoDB
|
|
81
|
+
DATABASE_URL="mongodb+srv://user:password@cluster.mongodb.net/mydb"
|
|
82
|
+
|
|
83
|
+
# CockroachDB
|
|
84
|
+
DATABASE_URL="postgresql://user:password@localhost:26257/mydb"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Step 4: Generate Client and Push Schema
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
prisma db push
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Or separately:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
prisma generate
|
|
97
|
+
prisma db push
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
For auto-regeneration during development:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
prisma generate --watch
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Initialization
|
|
109
|
+
|
|
110
|
+
### Async Client (Recommended)
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
import asyncio
|
|
114
|
+
from prisma import Prisma
|
|
115
|
+
|
|
116
|
+
async def main() -> None:
|
|
117
|
+
db = Prisma()
|
|
118
|
+
await db.connect()
|
|
119
|
+
|
|
120
|
+
# Your database queries here
|
|
121
|
+
|
|
122
|
+
await db.disconnect()
|
|
123
|
+
|
|
124
|
+
if __name__ == '__main__':
|
|
125
|
+
asyncio.run(main())
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Sync Client
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
from prisma import Prisma
|
|
132
|
+
|
|
133
|
+
db = Prisma()
|
|
134
|
+
db.connect()
|
|
135
|
+
|
|
136
|
+
# Your database queries here
|
|
137
|
+
|
|
138
|
+
db.disconnect()
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Context Manager (Auto Connect/Disconnect)
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
import asyncio
|
|
145
|
+
from prisma import Prisma
|
|
146
|
+
|
|
147
|
+
async def main() -> None:
|
|
148
|
+
async with Prisma() as db:
|
|
149
|
+
# Database operations here
|
|
150
|
+
user = await db.user.create(
|
|
151
|
+
data={'name': 'Alice', 'email': 'alice@prisma.io'}
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
if __name__ == '__main__':
|
|
155
|
+
asyncio.run(main())
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Client with Auto-Register (Model-Based Access)
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
from prisma import Prisma
|
|
162
|
+
from prisma.models import User
|
|
163
|
+
|
|
164
|
+
async def main() -> None:
|
|
165
|
+
db = Prisma(auto_register=True)
|
|
166
|
+
await db.connect()
|
|
167
|
+
|
|
168
|
+
# Access via model
|
|
169
|
+
user = await User.prisma().create(
|
|
170
|
+
data={'name': 'Alice', 'email': 'alice@prisma.io'}
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
await db.disconnect()
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Schema Definition
|
|
179
|
+
|
|
180
|
+
### Basic Schema
|
|
181
|
+
|
|
182
|
+
```prisma
|
|
183
|
+
datasource db {
|
|
184
|
+
provider = "postgresql"
|
|
185
|
+
url = env("DATABASE_URL")
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
generator client {
|
|
189
|
+
provider = "prisma-client-py"
|
|
190
|
+
recursive_type_depth = 5
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
model User {
|
|
194
|
+
id Int @id @default(autoincrement())
|
|
195
|
+
email String @unique
|
|
196
|
+
name String?
|
|
197
|
+
createdAt DateTime @default(now())
|
|
198
|
+
updatedAt DateTime @updatedAt
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Field Types
|
|
203
|
+
|
|
204
|
+
```prisma
|
|
205
|
+
model Example {
|
|
206
|
+
id Int @id @default(autoincrement())
|
|
207
|
+
string String
|
|
208
|
+
int Int
|
|
209
|
+
bigInt BigInt
|
|
210
|
+
float Float
|
|
211
|
+
decimal Decimal
|
|
212
|
+
boolean Boolean
|
|
213
|
+
dateTime DateTime
|
|
214
|
+
json Json
|
|
215
|
+
bytes Bytes
|
|
216
|
+
optional String?
|
|
217
|
+
array String[]
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Field Attributes
|
|
222
|
+
|
|
223
|
+
```prisma
|
|
224
|
+
model User {
|
|
225
|
+
id Int @id @default(autoincrement())
|
|
226
|
+
uuid String @default(uuid())
|
|
227
|
+
email String @unique
|
|
228
|
+
role String @default("USER")
|
|
229
|
+
createdAt DateTime @default(now())
|
|
230
|
+
updatedAt DateTime @updatedAt
|
|
231
|
+
|
|
232
|
+
@@unique([email, name])
|
|
233
|
+
@@index([email])
|
|
234
|
+
@@map("users")
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Enums
|
|
239
|
+
|
|
240
|
+
```prisma
|
|
241
|
+
enum Role {
|
|
242
|
+
USER
|
|
243
|
+
ADMIN
|
|
244
|
+
MODERATOR
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
model User {
|
|
248
|
+
id Int @id @default(autoincrement())
|
|
249
|
+
role Role @default(USER)
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## Relations
|
|
256
|
+
|
|
257
|
+
### One-to-One
|
|
258
|
+
|
|
259
|
+
```prisma
|
|
260
|
+
model User {
|
|
261
|
+
id Int @id @default(autoincrement())
|
|
262
|
+
email String @unique
|
|
263
|
+
profile Profile?
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
model Profile {
|
|
267
|
+
id Int @id @default(autoincrement())
|
|
268
|
+
bio String
|
|
269
|
+
user User @relation(fields: [userId], references: [id])
|
|
270
|
+
userId Int @unique
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### One-to-Many
|
|
275
|
+
|
|
276
|
+
```prisma
|
|
277
|
+
model User {
|
|
278
|
+
id Int @id @default(autoincrement())
|
|
279
|
+
email String @unique
|
|
280
|
+
posts Post[]
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
model Post {
|
|
284
|
+
id Int @id @default(autoincrement())
|
|
285
|
+
title String
|
|
286
|
+
author User @relation(fields: [authorId], references: [id])
|
|
287
|
+
authorId Int
|
|
288
|
+
}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Many-to-Many (Implicit)
|
|
292
|
+
|
|
293
|
+
```prisma
|
|
294
|
+
model Post {
|
|
295
|
+
id Int @id @default(autoincrement())
|
|
296
|
+
title String
|
|
297
|
+
categories Category[]
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
model Category {
|
|
301
|
+
id Int @id @default(autoincrement())
|
|
302
|
+
name String
|
|
303
|
+
posts Post[]
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Many-to-Many (Explicit)
|
|
308
|
+
|
|
309
|
+
```prisma
|
|
310
|
+
model Post {
|
|
311
|
+
id Int @id @default(autoincrement())
|
|
312
|
+
title String
|
|
313
|
+
postCategories PostCategory[]
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
model Category {
|
|
317
|
+
id Int @id @default(autoincrement())
|
|
318
|
+
name String
|
|
319
|
+
postCategories PostCategory[]
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
model PostCategory {
|
|
323
|
+
post Post @relation(fields: [postId], references: [id])
|
|
324
|
+
postId Int
|
|
325
|
+
category Category @relation(fields: [categoryId], references: [id])
|
|
326
|
+
categoryId Int
|
|
327
|
+
assignedAt DateTime @default(now())
|
|
328
|
+
|
|
329
|
+
@@id([postId, categoryId])
|
|
330
|
+
}
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## CRUD Operations
|
|
336
|
+
|
|
337
|
+
### Create
|
|
338
|
+
|
|
339
|
+
#### Single Record
|
|
340
|
+
|
|
341
|
+
```python
|
|
342
|
+
user = await db.user.create(
|
|
343
|
+
data={
|
|
344
|
+
'email': 'alice@prisma.io',
|
|
345
|
+
'name': 'Alice',
|
|
346
|
+
}
|
|
347
|
+
)
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
#### Multiple Records
|
|
351
|
+
|
|
352
|
+
```python
|
|
353
|
+
count = await db.user.create_many(
|
|
354
|
+
data=[
|
|
355
|
+
{'email': 'bob@prisma.io', 'name': 'Bob'},
|
|
356
|
+
{'email': 'charlie@prisma.io', 'name': 'Charlie'},
|
|
357
|
+
],
|
|
358
|
+
skip_duplicates=True,
|
|
359
|
+
)
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
#### Create with Relations
|
|
363
|
+
|
|
364
|
+
```python
|
|
365
|
+
user = await db.user.create(
|
|
366
|
+
data={
|
|
367
|
+
'email': 'alice@prisma.io',
|
|
368
|
+
'name': 'Alice',
|
|
369
|
+
'posts': {
|
|
370
|
+
'create': [
|
|
371
|
+
{'title': 'First Post', 'published': True},
|
|
372
|
+
{'title': 'Second Post', 'published': False},
|
|
373
|
+
]
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
)
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
#### Create with Nested Relations
|
|
380
|
+
|
|
381
|
+
```python
|
|
382
|
+
user = await db.user.create(
|
|
383
|
+
data={
|
|
384
|
+
'email': 'alice@prisma.io',
|
|
385
|
+
'name': 'Alice',
|
|
386
|
+
'posts': {
|
|
387
|
+
'create': {
|
|
388
|
+
'title': 'Hello World',
|
|
389
|
+
'categories': {
|
|
390
|
+
'create': [
|
|
391
|
+
{'name': 'Tech'},
|
|
392
|
+
{'name': 'News'},
|
|
393
|
+
]
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
)
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
### Read
|
|
402
|
+
|
|
403
|
+
#### Find Unique
|
|
404
|
+
|
|
405
|
+
```python
|
|
406
|
+
user = await db.user.find_unique(
|
|
407
|
+
where={'email': 'alice@prisma.io'}
|
|
408
|
+
)
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
#### Find Unique or Raise
|
|
412
|
+
|
|
413
|
+
```python
|
|
414
|
+
user = await db.user.find_unique_or_raise(
|
|
415
|
+
where={'id': 1}
|
|
416
|
+
)
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
#### Find First
|
|
420
|
+
|
|
421
|
+
```python
|
|
422
|
+
post = await db.post.find_first(
|
|
423
|
+
where={
|
|
424
|
+
'title': {'contains': 'Prisma'}
|
|
425
|
+
},
|
|
426
|
+
order={'createdAt': 'desc'}
|
|
427
|
+
)
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
#### Find First or Raise
|
|
431
|
+
|
|
432
|
+
```python
|
|
433
|
+
post = await db.post.find_first_or_raise(
|
|
434
|
+
where={'published': True}
|
|
435
|
+
)
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
#### Find Many
|
|
439
|
+
|
|
440
|
+
```python
|
|
441
|
+
users = await db.user.find_many()
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
#### Find Many with Filter
|
|
445
|
+
|
|
446
|
+
```python
|
|
447
|
+
users = await db.user.find_many(
|
|
448
|
+
where={
|
|
449
|
+
'email': {'endswith': 'prisma.io'},
|
|
450
|
+
'posts': {
|
|
451
|
+
'some': {
|
|
452
|
+
'published': True
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
)
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
#### Include Relations
|
|
460
|
+
|
|
461
|
+
```python
|
|
462
|
+
users = await db.user.find_many(
|
|
463
|
+
include={'posts': True}
|
|
464
|
+
)
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
#### Include with Nested Relations
|
|
468
|
+
|
|
469
|
+
```python
|
|
470
|
+
users = await db.user.find_many(
|
|
471
|
+
include={
|
|
472
|
+
'posts': {
|
|
473
|
+
'include': {
|
|
474
|
+
'categories': True
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
)
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
#### Include with Filtering
|
|
482
|
+
|
|
483
|
+
```python
|
|
484
|
+
users = await db.user.find_many(
|
|
485
|
+
include={
|
|
486
|
+
'posts': {
|
|
487
|
+
'where': {
|
|
488
|
+
'published': True
|
|
489
|
+
},
|
|
490
|
+
'order': {
|
|
491
|
+
'createdAt': 'desc'
|
|
492
|
+
},
|
|
493
|
+
'take': 5
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
)
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
### Update
|
|
500
|
+
|
|
501
|
+
#### Update Single Record
|
|
502
|
+
|
|
503
|
+
```python
|
|
504
|
+
user = await db.user.update(
|
|
505
|
+
where={'email': 'alice@prisma.io'},
|
|
506
|
+
data={'name': 'Alice Smith'}
|
|
507
|
+
)
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
#### Update Multiple Records
|
|
511
|
+
|
|
512
|
+
```python
|
|
513
|
+
count = await db.user.update_many(
|
|
514
|
+
where={
|
|
515
|
+
'email': {'contains': 'prisma.io'}
|
|
516
|
+
},
|
|
517
|
+
data={'role': 'ADMIN'}
|
|
518
|
+
)
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
#### Upsert (Update or Create)
|
|
522
|
+
|
|
523
|
+
```python
|
|
524
|
+
user = await db.user.upsert(
|
|
525
|
+
where={'email': 'alice@prisma.io'},
|
|
526
|
+
data={
|
|
527
|
+
'create': {
|
|
528
|
+
'email': 'alice@prisma.io',
|
|
529
|
+
'name': 'Alice'
|
|
530
|
+
},
|
|
531
|
+
'update': {
|
|
532
|
+
'name': 'Alice Updated'
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
)
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
#### Atomic Number Operations
|
|
539
|
+
|
|
540
|
+
```python
|
|
541
|
+
post = await db.post.update(
|
|
542
|
+
where={'id': 1},
|
|
543
|
+
data={
|
|
544
|
+
'views': {'increment': 1},
|
|
545
|
+
'likes': {'increment': 5}
|
|
546
|
+
}
|
|
547
|
+
)
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
```python
|
|
551
|
+
post = await db.post.update(
|
|
552
|
+
where={'id': 1},
|
|
553
|
+
data={
|
|
554
|
+
'views': {'decrement': 1},
|
|
555
|
+
'score': {'multiply': 2},
|
|
556
|
+
'total': {'divide': 10}
|
|
557
|
+
}
|
|
558
|
+
)
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
#### Update with Relations
|
|
562
|
+
|
|
563
|
+
```python
|
|
564
|
+
user = await db.user.update(
|
|
565
|
+
where={'id': 1},
|
|
566
|
+
data={
|
|
567
|
+
'posts': {
|
|
568
|
+
'create': {'title': 'New Post'}
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
)
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
#### Connect Existing Relations
|
|
575
|
+
|
|
576
|
+
```python
|
|
577
|
+
user = await db.user.update(
|
|
578
|
+
where={'id': 1},
|
|
579
|
+
data={
|
|
580
|
+
'posts': {
|
|
581
|
+
'connect': [{'id': 5}]
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
)
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
#### Disconnect Relations
|
|
588
|
+
|
|
589
|
+
```python
|
|
590
|
+
user = await db.user.update(
|
|
591
|
+
where={'id': 1},
|
|
592
|
+
data={
|
|
593
|
+
'posts': {
|
|
594
|
+
'disconnect': [{'id': 5}]
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
)
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
### Delete
|
|
601
|
+
|
|
602
|
+
#### Delete Single Record
|
|
603
|
+
|
|
604
|
+
```python
|
|
605
|
+
user = await db.user.delete(
|
|
606
|
+
where={'email': 'alice@prisma.io'}
|
|
607
|
+
)
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
#### Delete Multiple Records
|
|
611
|
+
|
|
612
|
+
```python
|
|
613
|
+
count = await db.user.delete_many(
|
|
614
|
+
where={
|
|
615
|
+
'email': {'contains': 'prisma.io'}
|
|
616
|
+
}
|
|
617
|
+
)
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
#### Delete All Records
|
|
621
|
+
|
|
622
|
+
```python
|
|
623
|
+
count = await db.user.delete_many()
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
---
|
|
627
|
+
|
|
628
|
+
## Filtering and Sorting
|
|
629
|
+
|
|
630
|
+
### Basic Filters
|
|
631
|
+
|
|
632
|
+
```python
|
|
633
|
+
users = await db.user.find_many(
|
|
634
|
+
where={
|
|
635
|
+
'email': {'equals': 'alice@prisma.io'},
|
|
636
|
+
'name': {'not': 'Bob'},
|
|
637
|
+
'age': {'gt': 18}
|
|
638
|
+
}
|
|
639
|
+
)
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
### String Filters
|
|
643
|
+
|
|
644
|
+
```python
|
|
645
|
+
users = await db.user.find_many(
|
|
646
|
+
where={
|
|
647
|
+
'email': {'startswith': 'alice'},
|
|
648
|
+
'name': {'endswith': 'Smith'},
|
|
649
|
+
'bio': {'contains': 'developer'}
|
|
650
|
+
}
|
|
651
|
+
)
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
### Number Filters
|
|
655
|
+
|
|
656
|
+
```python
|
|
657
|
+
posts = await db.post.find_many(
|
|
658
|
+
where={
|
|
659
|
+
'views': {'gt': 100},
|
|
660
|
+
'likes': {'gte': 50},
|
|
661
|
+
'comments': {'lt': 10},
|
|
662
|
+
'shares': {'lte': 5},
|
|
663
|
+
'rating': {'in': [4, 5]},
|
|
664
|
+
'score': {'not_in': [0, 1]}
|
|
665
|
+
}
|
|
666
|
+
)
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
### Logical Operators
|
|
670
|
+
|
|
671
|
+
```python
|
|
672
|
+
users = await db.user.find_many(
|
|
673
|
+
where={
|
|
674
|
+
'OR': [
|
|
675
|
+
{'email': {'contains': 'prisma.io'}},
|
|
676
|
+
{'name': {'contains': 'Alice'}}
|
|
677
|
+
]
|
|
678
|
+
}
|
|
679
|
+
)
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
```python
|
|
683
|
+
users = await db.user.find_many(
|
|
684
|
+
where={
|
|
685
|
+
'AND': [
|
|
686
|
+
{'email': {'contains': 'prisma.io'}},
|
|
687
|
+
{'role': 'ADMIN'}
|
|
688
|
+
]
|
|
689
|
+
}
|
|
690
|
+
)
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
```python
|
|
694
|
+
users = await db.user.find_many(
|
|
695
|
+
where={
|
|
696
|
+
'NOT': {
|
|
697
|
+
'email': {'contains': 'spam.com'}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
)
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
### Relation Filters
|
|
704
|
+
|
|
705
|
+
```python
|
|
706
|
+
users = await db.user.find_many(
|
|
707
|
+
where={
|
|
708
|
+
'posts': {
|
|
709
|
+
'some': {
|
|
710
|
+
'published': True
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
)
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
```python
|
|
718
|
+
users = await db.user.find_many(
|
|
719
|
+
where={
|
|
720
|
+
'posts': {
|
|
721
|
+
'every': {
|
|
722
|
+
'published': True
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
)
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
```python
|
|
730
|
+
users = await db.user.find_many(
|
|
731
|
+
where={
|
|
732
|
+
'posts': {
|
|
733
|
+
'none': {
|
|
734
|
+
'published': False
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
)
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
```python
|
|
742
|
+
posts = await db.post.find_many(
|
|
743
|
+
where={
|
|
744
|
+
'author': {
|
|
745
|
+
'is': {
|
|
746
|
+
'name': 'Alice'
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
)
|
|
751
|
+
```
|
|
752
|
+
|
|
753
|
+
```python
|
|
754
|
+
posts = await db.post.find_many(
|
|
755
|
+
where={
|
|
756
|
+
'author': {
|
|
757
|
+
'is_not': {
|
|
758
|
+
'role': 'BANNED'
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
)
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
### Sorting
|
|
766
|
+
|
|
767
|
+
```python
|
|
768
|
+
users = await db.user.find_many(
|
|
769
|
+
order={'name': 'asc'}
|
|
770
|
+
)
|
|
771
|
+
```
|
|
772
|
+
|
|
773
|
+
```python
|
|
774
|
+
users = await db.user.find_many(
|
|
775
|
+
order=[
|
|
776
|
+
{'role': 'desc'},
|
|
777
|
+
{'name': 'asc'}
|
|
778
|
+
]
|
|
779
|
+
)
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
---
|
|
783
|
+
|
|
784
|
+
## Pagination
|
|
785
|
+
|
|
786
|
+
### Offset Pagination
|
|
787
|
+
|
|
788
|
+
```python
|
|
789
|
+
users = await db.user.find_many(
|
|
790
|
+
skip=10,
|
|
791
|
+
take=10
|
|
792
|
+
)
|
|
793
|
+
```
|
|
794
|
+
|
|
795
|
+
### Cursor-Based Pagination
|
|
796
|
+
|
|
797
|
+
```python
|
|
798
|
+
users = await db.user.find_many(
|
|
799
|
+
take=10,
|
|
800
|
+
cursor={'id': last_user_id},
|
|
801
|
+
skip=1 # Skip cursor itself
|
|
802
|
+
)
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
---
|
|
806
|
+
|
|
807
|
+
## Aggregation
|
|
808
|
+
|
|
809
|
+
### Count
|
|
810
|
+
|
|
811
|
+
```python
|
|
812
|
+
count = await db.user.count()
|
|
813
|
+
```
|
|
814
|
+
|
|
815
|
+
```python
|
|
816
|
+
count = await db.user.count(
|
|
817
|
+
where={
|
|
818
|
+
'email': {'contains': 'prisma.io'}
|
|
819
|
+
}
|
|
820
|
+
)
|
|
821
|
+
```
|
|
822
|
+
|
|
823
|
+
### Group By
|
|
824
|
+
|
|
825
|
+
```python
|
|
826
|
+
results = await db.user.group_by(
|
|
827
|
+
by=['role']
|
|
828
|
+
)
|
|
829
|
+
```
|
|
830
|
+
|
|
831
|
+
```python
|
|
832
|
+
results = await db.user.group_by(
|
|
833
|
+
by=['country'],
|
|
834
|
+
count={'_all': True}
|
|
835
|
+
)
|
|
836
|
+
```
|
|
837
|
+
|
|
838
|
+
```python
|
|
839
|
+
results = await db.user.group_by(
|
|
840
|
+
by=['country'],
|
|
841
|
+
count={'_all': True, 'city': True},
|
|
842
|
+
sum={'views': True},
|
|
843
|
+
avg={'age': True},
|
|
844
|
+
order={'country': 'desc'},
|
|
845
|
+
having={
|
|
846
|
+
'age': {
|
|
847
|
+
'_avg': {
|
|
848
|
+
'gt': 18
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
)
|
|
853
|
+
```
|
|
854
|
+
|
|
855
|
+
```python
|
|
856
|
+
results = await db.post.group_by(
|
|
857
|
+
by=['authorId'],
|
|
858
|
+
count={'_all': True},
|
|
859
|
+
order={
|
|
860
|
+
'_count': {
|
|
861
|
+
'_all': 'desc'
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
)
|
|
865
|
+
```
|
|
866
|
+
|
|
867
|
+
---
|
|
868
|
+
|
|
869
|
+
## Transactions
|
|
870
|
+
|
|
871
|
+
### Transaction with Context Manager (Async)
|
|
872
|
+
|
|
873
|
+
```python
|
|
874
|
+
async with db.tx() as transaction:
|
|
875
|
+
user = await transaction.user.update(
|
|
876
|
+
where={'id': from_user_id},
|
|
877
|
+
data={'balance': {'decrement': 50}}
|
|
878
|
+
)
|
|
879
|
+
|
|
880
|
+
if user.balance < 0:
|
|
881
|
+
raise ValueError(f'{user.name} does not have enough balance')
|
|
882
|
+
|
|
883
|
+
await transaction.user.update(
|
|
884
|
+
where={'id': to_user_id},
|
|
885
|
+
data={'balance': {'increment': 50}}
|
|
886
|
+
)
|
|
887
|
+
```
|
|
888
|
+
|
|
889
|
+
### Transaction with Context Manager (Sync)
|
|
890
|
+
|
|
891
|
+
```python
|
|
892
|
+
with db.tx() as transaction:
|
|
893
|
+
user = transaction.user.update(
|
|
894
|
+
where={'id': from_user_id},
|
|
895
|
+
data={'balance': {'decrement': 50}}
|
|
896
|
+
)
|
|
897
|
+
|
|
898
|
+
if user.balance < 0:
|
|
899
|
+
raise ValueError(f'{user.name} does not have enough balance')
|
|
900
|
+
|
|
901
|
+
transaction.user.update(
|
|
902
|
+
where={'id': to_user_id},
|
|
903
|
+
data={'balance': {'increment': 50}}
|
|
904
|
+
)
|
|
905
|
+
```
|
|
906
|
+
|
|
907
|
+
### Manual Transaction Management
|
|
908
|
+
|
|
909
|
+
```python
|
|
910
|
+
transaction = db.tx()
|
|
911
|
+
await transaction.start()
|
|
912
|
+
|
|
913
|
+
try:
|
|
914
|
+
user = await transaction.user.create(
|
|
915
|
+
data={'email': 'alice@prisma.io', 'name': 'Alice'}
|
|
916
|
+
)
|
|
917
|
+
|
|
918
|
+
post = await transaction.post.create(
|
|
919
|
+
data={'title': 'Hello', 'authorId': user.id}
|
|
920
|
+
)
|
|
921
|
+
|
|
922
|
+
await transaction.commit()
|
|
923
|
+
except Exception as e:
|
|
924
|
+
await transaction.rollback()
|
|
925
|
+
raise e
|
|
926
|
+
```
|
|
927
|
+
|
|
928
|
+
---
|
|
929
|
+
|
|
930
|
+
## Raw Queries
|
|
931
|
+
|
|
932
|
+
### Raw Query (Select)
|
|
933
|
+
|
|
934
|
+
```python
|
|
935
|
+
results = await db.query_raw(
|
|
936
|
+
'SELECT * FROM "User" WHERE email = $1',
|
|
937
|
+
'alice@prisma.io'
|
|
938
|
+
)
|
|
939
|
+
```
|
|
940
|
+
|
|
941
|
+
### Raw Execute (Insert/Update/Delete)
|
|
942
|
+
|
|
943
|
+
```python
|
|
944
|
+
count = await db.execute_raw(
|
|
945
|
+
'UPDATE "User" SET name = $1 WHERE id = $2',
|
|
946
|
+
'Alice',
|
|
947
|
+
1
|
|
948
|
+
)
|
|
949
|
+
```
|
|
950
|
+
|
|
951
|
+
### Unsafe Raw Queries (Use with Caution)
|
|
952
|
+
|
|
953
|
+
```python
|
|
954
|
+
users = await db.query_raw('SELECT * FROM "User"')
|
|
955
|
+
```
|
|
956
|
+
|
|
957
|
+
---
|
|
958
|
+
|
|
959
|
+
## Advanced Features
|
|
960
|
+
|
|
961
|
+
### Distinct
|
|
962
|
+
|
|
963
|
+
```python
|
|
964
|
+
users = await db.user.find_many(
|
|
965
|
+
distinct=['email']
|
|
966
|
+
)
|
|
967
|
+
```
|
|
968
|
+
|
|
969
|
+
### Null Filtering
|
|
970
|
+
|
|
971
|
+
```python
|
|
972
|
+
users = await db.user.find_many(
|
|
973
|
+
where={
|
|
974
|
+
'name': {'not': None}
|
|
975
|
+
}
|
|
976
|
+
)
|
|
977
|
+
```
|
|
978
|
+
|
|
979
|
+
```python
|
|
980
|
+
users = await db.user.find_many(
|
|
981
|
+
where={
|
|
982
|
+
'name': None
|
|
983
|
+
}
|
|
984
|
+
)
|
|
985
|
+
```
|
|
986
|
+
|
|
987
|
+
### Case-Insensitive Filtering
|
|
988
|
+
|
|
989
|
+
```python
|
|
990
|
+
users = await db.user.find_many(
|
|
991
|
+
where={
|
|
992
|
+
'email': {
|
|
993
|
+
'equals': 'ALICE@PRISMA.IO',
|
|
994
|
+
'mode': 'insensitive'
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
)
|
|
998
|
+
```
|
|
999
|
+
|
|
1000
|
+
### Full-Text Search (PostgreSQL)
|
|
1001
|
+
|
|
1002
|
+
```python
|
|
1003
|
+
posts = await db.post.find_many(
|
|
1004
|
+
where={
|
|
1005
|
+
'title': {
|
|
1006
|
+
'search': 'database | prisma'
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
)
|
|
1010
|
+
```
|
|
1011
|
+
|
|
1012
|
+
---
|
|
1013
|
+
|
|
1014
|
+
## Type Safety
|
|
1015
|
+
|
|
1016
|
+
### Using Generated Types
|
|
1017
|
+
|
|
1018
|
+
```python
|
|
1019
|
+
from prisma.models import User
|
|
1020
|
+
from prisma.types import UserCreateInput, UserWhereInput
|
|
1021
|
+
|
|
1022
|
+
# Type-safe create input
|
|
1023
|
+
user_data: UserCreateInput = {
|
|
1024
|
+
'email': 'alice@prisma.io',
|
|
1025
|
+
'name': 'Alice'
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
user = await db.user.create(data=user_data)
|
|
1029
|
+
|
|
1030
|
+
# Type-safe where clause
|
|
1031
|
+
where: UserWhereInput = {
|
|
1032
|
+
'email': {'contains': 'prisma.io'}
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
users = await db.user.find_many(where=where)
|
|
1036
|
+
```
|
|
1037
|
+
|
|
1038
|
+
### Model Instance Methods
|
|
1039
|
+
|
|
1040
|
+
```python
|
|
1041
|
+
from prisma.models import User
|
|
1042
|
+
|
|
1043
|
+
user = await User.prisma().create(
|
|
1044
|
+
data={'email': 'alice@prisma.io', 'name': 'Alice'}
|
|
1045
|
+
)
|
|
1046
|
+
|
|
1047
|
+
# Access fields
|
|
1048
|
+
print(user.id)
|
|
1049
|
+
print(user.email)
|
|
1050
|
+
print(user.name)
|
|
1051
|
+
|
|
1052
|
+
# Update instance
|
|
1053
|
+
updated_user = await user.update(
|
|
1054
|
+
data={'name': 'Alice Smith'}
|
|
1055
|
+
)
|
|
1056
|
+
|
|
1057
|
+
# Delete instance
|
|
1058
|
+
await user.delete()
|
|
1059
|
+
```
|
|
1060
|
+
|
|
1061
|
+
---
|
|
1062
|
+
|
|
1063
|
+
## Database-Specific Features
|
|
1064
|
+
|
|
1065
|
+
### PostgreSQL
|
|
1066
|
+
|
|
1067
|
+
```prisma
|
|
1068
|
+
model User {
|
|
1069
|
+
id Int @id @default(autoincrement())
|
|
1070
|
+
data Json @db.JsonB
|
|
1071
|
+
tags String[] @db.VarChar(255)
|
|
1072
|
+
}
|
|
1073
|
+
```
|
|
1074
|
+
|
|
1075
|
+
### MySQL
|
|
1076
|
+
|
|
1077
|
+
```prisma
|
|
1078
|
+
model User {
|
|
1079
|
+
id Int @id @default(autoincrement())
|
|
1080
|
+
name String @db.VarChar(255)
|
|
1081
|
+
bio String @db.Text
|
|
1082
|
+
}
|
|
1083
|
+
```
|
|
1084
|
+
|
|
1085
|
+
### SQLite
|
|
1086
|
+
|
|
1087
|
+
```prisma
|
|
1088
|
+
datasource db {
|
|
1089
|
+
provider = "sqlite"
|
|
1090
|
+
url = "file:./dev.db"
|
|
1091
|
+
}
|
|
1092
|
+
```
|
|
1093
|
+
|
|
1094
|
+
### MongoDB
|
|
1095
|
+
|
|
1096
|
+
```prisma
|
|
1097
|
+
datasource db {
|
|
1098
|
+
provider = "mongodb"
|
|
1099
|
+
url = env("DATABASE_URL")
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
model User {
|
|
1103
|
+
id String @id @default(auto()) @map("_id") @db.ObjectId
|
|
1104
|
+
email String @unique
|
|
1105
|
+
}
|
|
1106
|
+
```
|
|
1107
|
+
|
|
1108
|
+
---
|
|
1109
|
+
|
|
1110
|
+
## Complete Example Application
|
|
1111
|
+
|
|
1112
|
+
```python
|
|
1113
|
+
import asyncio
|
|
1114
|
+
from prisma import Prisma
|
|
1115
|
+
from prisma.models import User, Post
|
|
1116
|
+
|
|
1117
|
+
async def main() -> None:
|
|
1118
|
+
db = Prisma()
|
|
1119
|
+
await db.connect()
|
|
1120
|
+
|
|
1121
|
+
# Create user with posts
|
|
1122
|
+
user = await db.user.create(
|
|
1123
|
+
data={
|
|
1124
|
+
'email': 'alice@prisma.io',
|
|
1125
|
+
'name': 'Alice',
|
|
1126
|
+
'posts': {
|
|
1127
|
+
'create': [
|
|
1128
|
+
{
|
|
1129
|
+
'title': 'Getting Started with Prisma',
|
|
1130
|
+
'content': 'Learn how to use Prisma...',
|
|
1131
|
+
'published': True
|
|
1132
|
+
},
|
|
1133
|
+
{
|
|
1134
|
+
'title': 'Advanced Prisma Patterns',
|
|
1135
|
+
'content': 'Dive deeper...',
|
|
1136
|
+
'published': False
|
|
1137
|
+
}
|
|
1138
|
+
]
|
|
1139
|
+
}
|
|
1140
|
+
},
|
|
1141
|
+
include={'posts': True}
|
|
1142
|
+
)
|
|
1143
|
+
print(f'Created user: {user}')
|
|
1144
|
+
|
|
1145
|
+
# Find all published posts with author
|
|
1146
|
+
published_posts = await db.post.find_many(
|
|
1147
|
+
where={'published': True},
|
|
1148
|
+
include={'author': True}
|
|
1149
|
+
)
|
|
1150
|
+
print(f'Published posts: {published_posts}')
|
|
1151
|
+
|
|
1152
|
+
# Update post
|
|
1153
|
+
updated_post = await db.post.update(
|
|
1154
|
+
where={'id': 1},
|
|
1155
|
+
data={'views': {'increment': 1}}
|
|
1156
|
+
)
|
|
1157
|
+
print(f'Updated post: {updated_post}')
|
|
1158
|
+
|
|
1159
|
+
# Aggregate data
|
|
1160
|
+
stats = await db.post.group_by(
|
|
1161
|
+
by=['published'],
|
|
1162
|
+
count={'_all': True},
|
|
1163
|
+
avg={'views': True}
|
|
1164
|
+
)
|
|
1165
|
+
print(f'Post statistics: {stats}')
|
|
1166
|
+
|
|
1167
|
+
# Transaction
|
|
1168
|
+
async with db.tx() as transaction:
|
|
1169
|
+
new_user = await transaction.user.create(
|
|
1170
|
+
data={
|
|
1171
|
+
'email': 'bob@prisma.io',
|
|
1172
|
+
'name': 'Bob'
|
|
1173
|
+
}
|
|
1174
|
+
)
|
|
1175
|
+
|
|
1176
|
+
new_post = await transaction.post.create(
|
|
1177
|
+
data={
|
|
1178
|
+
'title': "Bob's First Post",
|
|
1179
|
+
'authorId': new_user.id
|
|
1180
|
+
}
|
|
1181
|
+
)
|
|
1182
|
+
|
|
1183
|
+
print(f'Transaction completed: {new_user}, {new_post}')
|
|
1184
|
+
|
|
1185
|
+
await db.disconnect()
|
|
1186
|
+
|
|
1187
|
+
if __name__ == '__main__':
|
|
1188
|
+
asyncio.run(main())
|
|
1189
|
+
```
|
|
1190
|
+
|
|
1191
|
+
---
|
|
1192
|
+
|
|
1193
|
+
## Batch Operations
|
|
1194
|
+
|
|
1195
|
+
### Batch Queries
|
|
1196
|
+
|
|
1197
|
+
```python
|
|
1198
|
+
# Execute multiple queries in parallel
|
|
1199
|
+
users, posts = await asyncio.gather(
|
|
1200
|
+
db.user.find_many(),
|
|
1201
|
+
db.post.find_many()
|
|
1202
|
+
)
|
|
1203
|
+
```
|
|
1204
|
+
|
|
1205
|
+
### Batch Creates
|
|
1206
|
+
|
|
1207
|
+
```python
|
|
1208
|
+
users = await db.user.create_many(
|
|
1209
|
+
data=[
|
|
1210
|
+
{'email': f'user{i}@example.com', 'name': f'User {i}'}
|
|
1211
|
+
for i in range(100)
|
|
1212
|
+
]
|
|
1213
|
+
)
|
|
1214
|
+
```
|
|
1215
|
+
|
|
1216
|
+
---
|
|
1217
|
+
|
|
1218
|
+
## Error Handling
|
|
1219
|
+
|
|
1220
|
+
```python
|
|
1221
|
+
from prisma.errors import (
|
|
1222
|
+
UniqueViolationError,
|
|
1223
|
+
RecordNotFoundError,
|
|
1224
|
+
PrismaError
|
|
1225
|
+
)
|
|
1226
|
+
|
|
1227
|
+
try:
|
|
1228
|
+
user = await db.user.create(
|
|
1229
|
+
data={'email': 'alice@prisma.io', 'name': 'Alice'}
|
|
1230
|
+
)
|
|
1231
|
+
except UniqueViolationError:
|
|
1232
|
+
print('User with this email already exists')
|
|
1233
|
+
except RecordNotFoundError:
|
|
1234
|
+
print('Record not found')
|
|
1235
|
+
except PrismaError as e:
|
|
1236
|
+
print(f'Database error: {e}')
|
|
1237
|
+
```
|
|
1238
|
+
|
|
1239
|
+
---
|
|
1240
|
+
|
|
1241
|
+
## Connection Management
|
|
1242
|
+
|
|
1243
|
+
### Connect and Disconnect
|
|
1244
|
+
|
|
1245
|
+
```python
|
|
1246
|
+
db = Prisma()
|
|
1247
|
+
await db.connect()
|
|
1248
|
+
|
|
1249
|
+
# Perform operations
|
|
1250
|
+
|
|
1251
|
+
await db.disconnect()
|
|
1252
|
+
```
|
|
1253
|
+
|
|
1254
|
+
### Check Connection Status
|
|
1255
|
+
|
|
1256
|
+
```python
|
|
1257
|
+
if db.is_connected():
|
|
1258
|
+
print('Connected to database')
|
|
1259
|
+
else:
|
|
1260
|
+
print('Not connected')
|
|
1261
|
+
```
|
|
1262
|
+
|
|
1263
|
+
### Connection Pooling
|
|
1264
|
+
|
|
1265
|
+
Prisma Client Python handles connection pooling automatically based on the underlying Prisma engine configuration.
|
|
1266
|
+
|
|
1267
|
+
---
|
|
1268
|
+
|
|
1269
|
+
## CLI Commands
|
|
1270
|
+
|
|
1271
|
+
### Generate Client
|
|
1272
|
+
|
|
1273
|
+
```bash
|
|
1274
|
+
prisma generate
|
|
1275
|
+
```
|
|
1276
|
+
|
|
1277
|
+
### Push Schema to Database
|
|
1278
|
+
|
|
1279
|
+
```bash
|
|
1280
|
+
prisma db push
|
|
1281
|
+
```
|
|
1282
|
+
|
|
1283
|
+
### Create Migration
|
|
1284
|
+
|
|
1285
|
+
```bash
|
|
1286
|
+
prisma migrate dev --name init
|
|
1287
|
+
```
|
|
1288
|
+
|
|
1289
|
+
### Apply Migrations
|
|
1290
|
+
|
|
1291
|
+
```bash
|
|
1292
|
+
prisma migrate deploy
|
|
1293
|
+
```
|
|
1294
|
+
|
|
1295
|
+
### Reset Database
|
|
1296
|
+
|
|
1297
|
+
```bash
|
|
1298
|
+
prisma migrate reset
|
|
1299
|
+
```
|
|
1300
|
+
|
|
1301
|
+
### Open Prisma Studio
|
|
1302
|
+
|
|
1303
|
+
```bash
|
|
1304
|
+
prisma studio
|
|
1305
|
+
```
|
|
1306
|
+
|
|
1307
|
+
### Format Schema
|
|
1308
|
+
|
|
1309
|
+
```bash
|
|
1310
|
+
prisma format
|
|
1311
|
+
```
|
|
1312
|
+
|
|
1313
|
+
### Validate Schema
|
|
1314
|
+
|
|
1315
|
+
```bash
|
|
1316
|
+
prisma validate
|
|
1317
|
+
```
|