prisma-sql 1.2.0 → 1.3.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/dist/index.cjs +21 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +6 -5
- package/dist/index.d.ts +6 -5
- package/dist/index.js +18 -21
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/readme.md +111 -161
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -3,10 +3,15 @@
|
|
|
3
3
|
Speed up Prisma reads **2-7x** by executing queries via postgres.js instead of Prisma's query engine.
|
|
4
4
|
|
|
5
5
|
```typescript
|
|
6
|
+
import { convertDMMFToModels } from 'prisma-sql'
|
|
7
|
+
import { Prisma } from '@prisma/client'
|
|
8
|
+
|
|
9
|
+
const models = convertDMMFToModels(Prisma.dmmf.datamodel)
|
|
6
10
|
const sql = postgres(DATABASE_URL)
|
|
7
|
-
const prisma = new PrismaClient().$extends(
|
|
11
|
+
const prisma = new PrismaClient().$extends(
|
|
12
|
+
speedExtension({ postgres: sql, models }),
|
|
13
|
+
)
|
|
8
14
|
|
|
9
|
-
// Same Prisma API, 2-7x faster reads
|
|
10
15
|
const users = await prisma.user.findMany({ where: { status: 'ACTIVE' } })
|
|
11
16
|
```
|
|
12
17
|
|
|
@@ -42,14 +47,16 @@ npm install prisma-sql better-sqlite3
|
|
|
42
47
|
### PostgreSQL
|
|
43
48
|
|
|
44
49
|
```typescript
|
|
45
|
-
import { PrismaClient } from '@prisma/client'
|
|
46
|
-
import { speedExtension } from 'prisma-sql'
|
|
50
|
+
import { PrismaClient, Prisma } from '@prisma/client'
|
|
51
|
+
import { speedExtension, convertDMMFToModels } from 'prisma-sql'
|
|
47
52
|
import postgres from 'postgres'
|
|
48
53
|
|
|
54
|
+
const models = convertDMMFToModels(Prisma.dmmf.datamodel)
|
|
49
55
|
const sql = postgres(process.env.DATABASE_URL)
|
|
50
|
-
const prisma = new PrismaClient().$extends(
|
|
56
|
+
const prisma = new PrismaClient().$extends(
|
|
57
|
+
speedExtension({ postgres: sql, models }),
|
|
58
|
+
)
|
|
51
59
|
|
|
52
|
-
// All reads now execute via postgres.js
|
|
53
60
|
const users = await prisma.user.findMany({
|
|
54
61
|
where: { status: 'ACTIVE' },
|
|
55
62
|
include: { posts: true },
|
|
@@ -59,32 +66,17 @@ const users = await prisma.user.findMany({
|
|
|
59
66
|
### SQLite
|
|
60
67
|
|
|
61
68
|
```typescript
|
|
62
|
-
import { PrismaClient } from '@prisma/client'
|
|
63
|
-
import { speedExtension } from 'prisma-sql'
|
|
69
|
+
import { PrismaClient, Prisma } from '@prisma/client'
|
|
70
|
+
import { speedExtension, convertDMMFToModels } from 'prisma-sql'
|
|
64
71
|
import Database from 'better-sqlite3'
|
|
65
72
|
|
|
73
|
+
const models = convertDMMFToModels(Prisma.dmmf.datamodel)
|
|
66
74
|
const db = new Database('./data.db')
|
|
67
|
-
const prisma = new PrismaClient().$extends(speedExtension({ sqlite: db }))
|
|
68
|
-
|
|
69
|
-
const users = await prisma.user.findMany({ where: { status: 'ACTIVE' } })
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### Explicit DMMF (Edge Runtimes)
|
|
73
|
-
|
|
74
|
-
In some environments (Cloudflare Workers, Vercel Edge, bundlers), Prisma's DMMF may not be auto-detectable. Provide it explicitly:
|
|
75
|
-
|
|
76
|
-
```typescript
|
|
77
|
-
import { PrismaClient, Prisma } from '@prisma/client'
|
|
78
|
-
import { speedExtension } from 'prisma-sql'
|
|
79
|
-
import postgres from 'postgres'
|
|
80
|
-
|
|
81
|
-
const sql = postgres(process.env.DATABASE_URL)
|
|
82
75
|
const prisma = new PrismaClient().$extends(
|
|
83
|
-
speedExtension({
|
|
84
|
-
postgres: sql,
|
|
85
|
-
dmmf: Prisma.dmmf, // Required in edge runtimes
|
|
86
|
-
}),
|
|
76
|
+
speedExtension({ sqlite: db, models }),
|
|
87
77
|
)
|
|
78
|
+
|
|
79
|
+
const users = await prisma.user.findMany({ where: { status: 'ACTIVE' } })
|
|
88
80
|
```
|
|
89
81
|
|
|
90
82
|
## What Gets Faster
|
|
@@ -271,22 +263,18 @@ Benchmarks from 137 E2E tests comparing identical queries against Prisma v6, Pri
|
|
|
271
263
|
|
|
272
264
|
```typescript
|
|
273
265
|
import { Prisma } from '@prisma/client'
|
|
266
|
+
import { convertDMMFToModels } from 'prisma-sql'
|
|
274
267
|
|
|
275
|
-
|
|
276
|
-
// Database client (required - choose one)
|
|
277
|
-
postgres: sql, // For PostgreSQL via postgres.js
|
|
278
|
-
sqlite: db, // For SQLite via better-sqlite3
|
|
268
|
+
const models = convertDMMFToModels(Prisma.dmmf.datamodel)
|
|
279
269
|
|
|
280
|
-
|
|
281
|
-
|
|
270
|
+
speedExtension({
|
|
271
|
+
postgres: sql,
|
|
272
|
+
models,
|
|
282
273
|
|
|
283
|
-
|
|
284
|
-
debug: true, // Log all generated SQL
|
|
274
|
+
debug: true,
|
|
285
275
|
|
|
286
|
-
|
|
287
|
-
models: ['User', 'Post'], // Only accelerate these models
|
|
276
|
+
allowedModels: ['User', 'Post'],
|
|
288
277
|
|
|
289
|
-
// Performance monitoring (optional)
|
|
290
278
|
onQuery: (info) => {
|
|
291
279
|
console.log(`${info.model}.${info.method}: ${info.duration}ms`)
|
|
292
280
|
},
|
|
@@ -298,15 +286,16 @@ speedExtension({
|
|
|
298
286
|
See generated SQL for every query:
|
|
299
287
|
|
|
300
288
|
```typescript
|
|
289
|
+
import { convertDMMFToModels } from 'prisma-sql'
|
|
290
|
+
import { Prisma } from '@prisma/client'
|
|
291
|
+
|
|
292
|
+
const models = convertDMMFToModels(Prisma.dmmf.datamodel)
|
|
293
|
+
|
|
301
294
|
speedExtension({
|
|
302
295
|
postgres: sql,
|
|
296
|
+
models,
|
|
303
297
|
debug: true,
|
|
304
298
|
})
|
|
305
|
-
|
|
306
|
-
// Logs:
|
|
307
|
-
// [postgres] User.findMany
|
|
308
|
-
// SQL: SELECT ... FROM users WHERE status = $1
|
|
309
|
-
// Params: ['ACTIVE']
|
|
310
299
|
```
|
|
311
300
|
|
|
312
301
|
### Selective Models
|
|
@@ -314,12 +303,13 @@ speedExtension({
|
|
|
314
303
|
Only accelerate specific models:
|
|
315
304
|
|
|
316
305
|
```typescript
|
|
306
|
+
const models = convertDMMFToModels(Prisma.dmmf.datamodel)
|
|
307
|
+
|
|
317
308
|
speedExtension({
|
|
318
309
|
postgres: sql,
|
|
319
|
-
models
|
|
310
|
+
models,
|
|
311
|
+
allowedModels: ['User', 'Post'],
|
|
320
312
|
})
|
|
321
|
-
|
|
322
|
-
// Order, Product, etc. still use Prisma
|
|
323
313
|
```
|
|
324
314
|
|
|
325
315
|
### Performance Monitoring
|
|
@@ -327,8 +317,11 @@ speedExtension({
|
|
|
327
317
|
Track query performance:
|
|
328
318
|
|
|
329
319
|
```typescript
|
|
320
|
+
const models = convertDMMFToModels(Prisma.dmmf.datamodel)
|
|
321
|
+
|
|
330
322
|
speedExtension({
|
|
331
323
|
postgres: sql,
|
|
324
|
+
models,
|
|
332
325
|
onQuery: (info) => {
|
|
333
326
|
console.log(`${info.model}.${info.method} completed in ${info.duration}ms`)
|
|
334
327
|
|
|
@@ -343,24 +336,6 @@ speedExtension({
|
|
|
343
336
|
})
|
|
344
337
|
```
|
|
345
338
|
|
|
346
|
-
### When to Provide DMMF Explicitly
|
|
347
|
-
|
|
348
|
-
Provide `dmmf: Prisma.dmmf` if:
|
|
349
|
-
|
|
350
|
-
- Using Cloudflare Workers, Vercel Edge, or similar edge runtimes
|
|
351
|
-
- Bundling with webpack, esbuild, or Rollup
|
|
352
|
-
- In a monorepo with complex Prisma setup
|
|
353
|
-
- You see "Cannot access Prisma DMMF" error
|
|
354
|
-
|
|
355
|
-
```typescript
|
|
356
|
-
import { Prisma } from '@prisma/client'
|
|
357
|
-
|
|
358
|
-
speedExtension({
|
|
359
|
-
postgres: sql,
|
|
360
|
-
dmmf: Prisma.dmmf, // Explicit DMMF
|
|
361
|
-
})
|
|
362
|
-
```
|
|
363
|
-
|
|
364
339
|
## Advanced Usage
|
|
365
340
|
|
|
366
341
|
### Read Replicas
|
|
@@ -368,18 +343,20 @@ speedExtension({
|
|
|
368
343
|
Send writes to primary, reads to replica:
|
|
369
344
|
|
|
370
345
|
```typescript
|
|
371
|
-
|
|
346
|
+
import { convertDMMFToModels } from 'prisma-sql'
|
|
347
|
+
import { Prisma } from '@prisma/client'
|
|
348
|
+
|
|
349
|
+
const models = convertDMMFToModels(Prisma.dmmf.datamodel)
|
|
350
|
+
|
|
372
351
|
const primary = new PrismaClient()
|
|
373
352
|
|
|
374
|
-
// Replica for fast reads
|
|
375
353
|
const replica = postgres(process.env.REPLICA_URL)
|
|
376
354
|
const fastPrisma = new PrismaClient().$extends(
|
|
377
|
-
speedExtension({ postgres: replica })
|
|
355
|
+
speedExtension({ postgres: replica, models })
|
|
378
356
|
)
|
|
379
357
|
|
|
380
|
-
|
|
381
|
-
await
|
|
382
|
-
const users = await fastPrisma.user.findMany() // → Replica
|
|
358
|
+
await primary.user.create({ data: { ... } })
|
|
359
|
+
const users = await fastPrisma.user.findMany()
|
|
383
360
|
```
|
|
384
361
|
|
|
385
362
|
### Connection Pooling
|
|
@@ -387,14 +364,18 @@ const users = await fastPrisma.user.findMany() // → Replica
|
|
|
387
364
|
Configure postgres.js connection pool:
|
|
388
365
|
|
|
389
366
|
```typescript
|
|
367
|
+
const models = convertDMMFToModels(Prisma.dmmf.datamodel)
|
|
368
|
+
|
|
390
369
|
const sql = postgres(process.env.DATABASE_URL, {
|
|
391
|
-
max: 20,
|
|
392
|
-
idle_timeout: 20,
|
|
393
|
-
connect_timeout: 10,
|
|
394
|
-
ssl: 'require',
|
|
370
|
+
max: 20,
|
|
371
|
+
idle_timeout: 20,
|
|
372
|
+
connect_timeout: 10,
|
|
373
|
+
ssl: 'require',
|
|
395
374
|
})
|
|
396
375
|
|
|
397
|
-
const prisma = new PrismaClient().$extends(
|
|
376
|
+
const prisma = new PrismaClient().$extends(
|
|
377
|
+
speedExtension({ postgres: sql, models }),
|
|
378
|
+
)
|
|
398
379
|
```
|
|
399
380
|
|
|
400
381
|
### Gradual Rollout
|
|
@@ -402,28 +383,27 @@ const prisma = new PrismaClient().$extends(speedExtension({ postgres: sql }))
|
|
|
402
383
|
Feature-flag the extension for safe rollout:
|
|
403
384
|
|
|
404
385
|
```typescript
|
|
386
|
+
const models = convertDMMFToModels(Prisma.dmmf.datamodel)
|
|
405
387
|
const USE_FAST_READS = process.env.FAST_READS === 'true'
|
|
406
388
|
|
|
407
389
|
const sql = postgres(DATABASE_URL)
|
|
408
390
|
const prisma = new PrismaClient()
|
|
409
391
|
|
|
410
392
|
const db = USE_FAST_READS
|
|
411
|
-
? prisma.$extends(speedExtension({ postgres: sql }))
|
|
393
|
+
? prisma.$extends(speedExtension({ postgres: sql, models }))
|
|
412
394
|
: prisma
|
|
413
|
-
|
|
414
|
-
// Disable in production if issues arise:
|
|
415
|
-
// FAST_READS=false pm2 restart app
|
|
416
395
|
```
|
|
417
396
|
|
|
418
397
|
### Access Original Prisma
|
|
419
398
|
|
|
420
399
|
```typescript
|
|
421
|
-
const
|
|
400
|
+
const models = convertDMMFToModels(Prisma.dmmf.datamodel)
|
|
401
|
+
const prisma = new PrismaClient().$extends(
|
|
402
|
+
speedExtension({ postgres: sql, models }),
|
|
403
|
+
)
|
|
422
404
|
|
|
423
|
-
// Use extension (fast)
|
|
424
405
|
const fast = await prisma.user.findMany()
|
|
425
406
|
|
|
426
|
-
// Bypass extension (original Prisma)
|
|
427
407
|
const slow = await prisma.$original.user.findMany()
|
|
428
408
|
```
|
|
429
409
|
|
|
@@ -433,15 +413,13 @@ const slow = await prisma.$original.user.findMany()
|
|
|
433
413
|
|
|
434
414
|
```typescript
|
|
435
415
|
import { PrismaClient, Prisma } from '@prisma/client'
|
|
436
|
-
import { speedExtension } from 'prisma-sql'
|
|
416
|
+
import { speedExtension, convertDMMFToModels } from 'prisma-sql'
|
|
437
417
|
import postgres from 'postgres'
|
|
438
418
|
|
|
419
|
+
const models = convertDMMFToModels(Prisma.dmmf.datamodel)
|
|
439
420
|
const sql = postgres(process.env.DATABASE_URL)
|
|
440
421
|
const prisma = new PrismaClient().$extends(
|
|
441
|
-
speedExtension({
|
|
442
|
-
postgres: sql,
|
|
443
|
-
dmmf: Prisma.dmmf, // Explicit dmmf required in edge runtime
|
|
444
|
-
}),
|
|
422
|
+
speedExtension({ postgres: sql, models }),
|
|
445
423
|
)
|
|
446
424
|
|
|
447
425
|
export const config = { runtime: 'edge' }
|
|
@@ -457,10 +435,11 @@ export default async function handler(req: Request) {
|
|
|
457
435
|
For Cloudflare Workers, use the standalone SQL generation API instead of the extension:
|
|
458
436
|
|
|
459
437
|
```typescript
|
|
460
|
-
import { createToSQL } from 'prisma-sql'
|
|
438
|
+
import { createToSQL, convertDMMFToModels } from 'prisma-sql'
|
|
461
439
|
import { Prisma } from '@prisma/client'
|
|
462
440
|
|
|
463
|
-
const
|
|
441
|
+
const models = convertDMMFToModels(Prisma.dmmf.datamodel)
|
|
442
|
+
const toSQL = createToSQL(models, 'sqlite')
|
|
464
443
|
|
|
465
444
|
export default {
|
|
466
445
|
async fetch(request: Request, env: Env) {
|
|
@@ -483,23 +462,19 @@ export default {
|
|
|
483
462
|
### Filters
|
|
484
463
|
|
|
485
464
|
```typescript
|
|
486
|
-
// Comparison operators
|
|
487
465
|
{ age: { gt: 18, lte: 65 } }
|
|
488
466
|
{ status: { in: ['ACTIVE', 'PENDING'] } }
|
|
489
467
|
{ status: { notIn: ['DELETED'] } }
|
|
490
468
|
|
|
491
|
-
// String operations
|
|
492
469
|
{ email: { contains: '@example.com' } }
|
|
493
470
|
{ email: { startsWith: 'user' } }
|
|
494
471
|
{ email: { endsWith: '.com' } }
|
|
495
472
|
{ email: { contains: 'EXAMPLE', mode: 'insensitive' } }
|
|
496
473
|
|
|
497
|
-
// Logical operators
|
|
498
474
|
{ AND: [{ status: 'ACTIVE' }, { verified: true }] }
|
|
499
475
|
{ OR: [{ role: 'ADMIN' }, { role: 'MODERATOR' }] }
|
|
500
476
|
{ NOT: { status: 'DELETED' } }
|
|
501
477
|
|
|
502
|
-
// Null checks
|
|
503
478
|
{ deletedAt: null }
|
|
504
479
|
{ deletedAt: { not: null } }
|
|
505
480
|
```
|
|
@@ -507,7 +482,6 @@ export default {
|
|
|
507
482
|
### Relations
|
|
508
483
|
|
|
509
484
|
```typescript
|
|
510
|
-
// Include relations
|
|
511
485
|
{
|
|
512
486
|
include: {
|
|
513
487
|
posts: true,
|
|
@@ -515,7 +489,6 @@ export default {
|
|
|
515
489
|
}
|
|
516
490
|
}
|
|
517
491
|
|
|
518
|
-
// Nested includes
|
|
519
492
|
{
|
|
520
493
|
include: {
|
|
521
494
|
posts: {
|
|
@@ -527,7 +500,6 @@ export default {
|
|
|
527
500
|
}
|
|
528
501
|
}
|
|
529
502
|
|
|
530
|
-
// Relation filters
|
|
531
503
|
{
|
|
532
504
|
where: {
|
|
533
505
|
posts: {
|
|
@@ -556,22 +528,19 @@ export default {
|
|
|
556
528
|
### Pagination & Ordering
|
|
557
529
|
|
|
558
530
|
```typescript
|
|
559
|
-
// Limit/offset
|
|
560
531
|
{
|
|
561
532
|
take: 10,
|
|
562
533
|
skip: 20,
|
|
563
534
|
orderBy: { createdAt: 'desc' }
|
|
564
535
|
}
|
|
565
536
|
|
|
566
|
-
// Cursor-based pagination
|
|
567
537
|
{
|
|
568
538
|
cursor: { id: 100 },
|
|
569
539
|
take: 10,
|
|
570
|
-
skip: 1,
|
|
540
|
+
skip: 1,
|
|
571
541
|
orderBy: { id: 'asc' }
|
|
572
542
|
}
|
|
573
543
|
|
|
574
|
-
// Multiple ordering
|
|
575
544
|
{
|
|
576
545
|
orderBy: [
|
|
577
546
|
{ status: 'asc' },
|
|
@@ -580,7 +549,6 @@ export default {
|
|
|
580
549
|
]
|
|
581
550
|
}
|
|
582
551
|
|
|
583
|
-
// Null positioning (PostgreSQL)
|
|
584
552
|
{
|
|
585
553
|
orderBy: {
|
|
586
554
|
name: {
|
|
@@ -594,10 +562,8 @@ export default {
|
|
|
594
562
|
### Aggregations
|
|
595
563
|
|
|
596
564
|
```typescript
|
|
597
|
-
// Count
|
|
598
565
|
await prisma.user.count({ where: { status: 'ACTIVE' } })
|
|
599
566
|
|
|
600
|
-
// Multiple aggregations
|
|
601
567
|
await prisma.task.aggregate({
|
|
602
568
|
where: { status: 'DONE' },
|
|
603
569
|
_count: { _all: true },
|
|
@@ -607,7 +573,6 @@ await prisma.task.aggregate({
|
|
|
607
573
|
_max: { completedAt: true },
|
|
608
574
|
})
|
|
609
575
|
|
|
610
|
-
// Group by
|
|
611
576
|
await prisma.task.groupBy({
|
|
612
577
|
by: ['status', 'priority'],
|
|
613
578
|
_count: { _all: true },
|
|
@@ -623,13 +588,11 @@ await prisma.task.groupBy({
|
|
|
623
588
|
### Distinct
|
|
624
589
|
|
|
625
590
|
```typescript
|
|
626
|
-
// Single field (PostgreSQL uses DISTINCT ON)
|
|
627
591
|
{
|
|
628
592
|
distinct: ['status'],
|
|
629
593
|
orderBy: { status: 'asc' }
|
|
630
594
|
}
|
|
631
595
|
|
|
632
|
-
// Multiple fields (SQLite uses window functions)
|
|
633
596
|
{
|
|
634
597
|
distinct: ['status', 'priority'],
|
|
635
598
|
orderBy: [
|
|
@@ -654,12 +617,16 @@ const users = await prisma.user.findMany()
|
|
|
654
617
|
|
|
655
618
|
```typescript
|
|
656
619
|
import postgres from 'postgres'
|
|
657
|
-
import { speedExtension } from 'prisma-sql'
|
|
620
|
+
import { speedExtension, convertDMMFToModels } from 'prisma-sql'
|
|
621
|
+
import { Prisma } from '@prisma/client'
|
|
658
622
|
|
|
623
|
+
const models = convertDMMFToModels(Prisma.dmmf.datamodel)
|
|
659
624
|
const sql = postgres(DATABASE_URL)
|
|
660
|
-
const prisma = new PrismaClient().$extends(
|
|
625
|
+
const prisma = new PrismaClient().$extends(
|
|
626
|
+
speedExtension({ postgres: sql, models }),
|
|
627
|
+
)
|
|
661
628
|
|
|
662
|
-
const users = await prisma.user.findMany()
|
|
629
|
+
const users = await prisma.user.findMany()
|
|
663
630
|
```
|
|
664
631
|
|
|
665
632
|
### From Drizzle
|
|
@@ -682,12 +649,15 @@ const users = await db
|
|
|
682
649
|
**After:**
|
|
683
650
|
|
|
684
651
|
```typescript
|
|
685
|
-
import { speedExtension } from 'prisma-sql'
|
|
652
|
+
import { speedExtension, convertDMMFToModels } from 'prisma-sql'
|
|
653
|
+
import { Prisma } from '@prisma/client'
|
|
686
654
|
|
|
655
|
+
const models = convertDMMFToModels(Prisma.dmmf.datamodel)
|
|
687
656
|
const sql = postgres(DATABASE_URL)
|
|
688
|
-
const prisma = new PrismaClient().$extends(
|
|
657
|
+
const prisma = new PrismaClient().$extends(
|
|
658
|
+
speedExtension({ postgres: sql, models }),
|
|
659
|
+
)
|
|
689
660
|
|
|
690
|
-
// Use Prisma's familiar API instead
|
|
691
661
|
const users = await prisma.user.findMany({
|
|
692
662
|
where: { status: 'ACTIVE' },
|
|
693
663
|
})
|
|
@@ -724,13 +694,34 @@ If you encounter unsupported queries, enable `debug: true` to see which queries
|
|
|
724
694
|
|
|
725
695
|
## Troubleshooting
|
|
726
696
|
|
|
697
|
+
### "speedExtension requires models parameter"
|
|
698
|
+
|
|
699
|
+
Convert DMMF at module level:
|
|
700
|
+
|
|
701
|
+
```typescript
|
|
702
|
+
import { Prisma } from '@prisma/client'
|
|
703
|
+
import { convertDMMFToModels } from 'prisma-sql'
|
|
704
|
+
|
|
705
|
+
const models = convertDMMFToModels(Prisma.dmmf.datamodel)
|
|
706
|
+
|
|
707
|
+
const prisma = new PrismaClient().$extends(
|
|
708
|
+
speedExtension({
|
|
709
|
+
postgres: sql,
|
|
710
|
+
models,
|
|
711
|
+
}),
|
|
712
|
+
)
|
|
713
|
+
```
|
|
714
|
+
|
|
727
715
|
### "Results don't match Prisma Client"
|
|
728
716
|
|
|
729
717
|
Enable debug mode to inspect generated SQL:
|
|
730
718
|
|
|
731
719
|
```typescript
|
|
720
|
+
const models = convertDMMFToModels(Prisma.dmmf.datamodel)
|
|
721
|
+
|
|
732
722
|
speedExtension({
|
|
733
723
|
postgres: sql,
|
|
724
|
+
models,
|
|
734
725
|
debug: true,
|
|
735
726
|
})
|
|
736
727
|
```
|
|
@@ -749,38 +740,10 @@ Increase postgres.js pool size:
|
|
|
749
740
|
|
|
750
741
|
```typescript
|
|
751
742
|
const sql = postgres(DATABASE_URL, {
|
|
752
|
-
max: 50,
|
|
743
|
+
max: 50,
|
|
753
744
|
})
|
|
754
745
|
```
|
|
755
746
|
|
|
756
|
-
### "Cannot access Prisma DMMF" Error
|
|
757
|
-
|
|
758
|
-
If you see this error:
|
|
759
|
-
|
|
760
|
-
```
|
|
761
|
-
Cannot access Prisma DMMF. Please provide dmmf in config
|
|
762
|
-
```
|
|
763
|
-
|
|
764
|
-
Explicitly provide the DMMF:
|
|
765
|
-
|
|
766
|
-
```typescript
|
|
767
|
-
import { Prisma } from '@prisma/client'
|
|
768
|
-
|
|
769
|
-
const prisma = new PrismaClient().$extends(
|
|
770
|
-
speedExtension({
|
|
771
|
-
postgres: sql,
|
|
772
|
-
dmmf: Prisma.dmmf, // Add this
|
|
773
|
-
}),
|
|
774
|
-
)
|
|
775
|
-
```
|
|
776
|
-
|
|
777
|
-
This is required in:
|
|
778
|
-
|
|
779
|
-
- Edge runtimes (Cloudflare Workers, Vercel Edge)
|
|
780
|
-
- Bundled applications (webpack, esbuild)
|
|
781
|
-
- Some monorepo setups
|
|
782
|
-
- When using Prisma Client programmatically
|
|
783
|
-
|
|
784
747
|
### "Type errors after extending"
|
|
785
748
|
|
|
786
749
|
Ensure `@prisma/client` is up to date:
|
|
@@ -801,8 +764,11 @@ Some queries won't see dramatic improvements:
|
|
|
801
764
|
Use `onQuery` to measure actual speedup:
|
|
802
765
|
|
|
803
766
|
```typescript
|
|
767
|
+
const models = convertDMMFToModels(Prisma.dmmf.datamodel)
|
|
768
|
+
|
|
804
769
|
speedExtension({
|
|
805
770
|
postgres: sql,
|
|
771
|
+
models,
|
|
806
772
|
onQuery: (info) => {
|
|
807
773
|
console.log(`${info.method} took ${info.duration}ms`)
|
|
808
774
|
},
|
|
@@ -832,20 +798,6 @@ A: The extension runs after middlewares. If you need middleware to see the actua
|
|
|
832
798
|
**Q: Can I still use `$queryRaw` and `$executeRaw`?**
|
|
833
799
|
A: Yes. Those methods are unaffected. You also still have direct access to the postgres.js client.
|
|
834
800
|
|
|
835
|
-
**Q: Do I need to provide `dmmf` in the config?**
|
|
836
|
-
A: Usually no - it's auto-detected from Prisma Client. However, in edge runtimes (Cloudflare Workers, Vercel Edge) or bundled applications, you must provide it explicitly:
|
|
837
|
-
|
|
838
|
-
```typescript
|
|
839
|
-
import { Prisma } from '@prisma/client'
|
|
840
|
-
|
|
841
|
-
speedExtension({
|
|
842
|
-
postgres: sql,
|
|
843
|
-
dmmf: Prisma.dmmf, // Required in edge runtimes
|
|
844
|
-
})
|
|
845
|
-
```
|
|
846
|
-
|
|
847
|
-
If you see "Cannot access Prisma DMMF" error, add this parameter.
|
|
848
|
-
|
|
849
801
|
**Q: What's the overhead of SQL generation?**
|
|
850
802
|
A: ~0.03-0.04ms per query. Even with this overhead, total time is 2-7x faster than Prisma.
|
|
851
803
|
|
|
@@ -875,13 +827,16 @@ npm test
|
|
|
875
827
|
Benchmark your own queries:
|
|
876
828
|
|
|
877
829
|
```typescript
|
|
878
|
-
import { speedExtension } from 'prisma-sql'
|
|
830
|
+
import { speedExtension, convertDMMFToModels } from 'prisma-sql'
|
|
831
|
+
import { Prisma } from '@prisma/client'
|
|
879
832
|
|
|
880
833
|
const queries: { name: string; duration: number }[] = []
|
|
834
|
+
const models = convertDMMFToModels(Prisma.dmmf.datamodel)
|
|
881
835
|
|
|
882
836
|
const prisma = new PrismaClient().$extends(
|
|
883
837
|
speedExtension({
|
|
884
838
|
postgres: sql,
|
|
839
|
+
models,
|
|
885
840
|
onQuery: (info) => {
|
|
886
841
|
queries.push({
|
|
887
842
|
name: `${info.model}.${info.method}`,
|
|
@@ -891,11 +846,9 @@ const prisma = new PrismaClient().$extends(
|
|
|
891
846
|
}),
|
|
892
847
|
)
|
|
893
848
|
|
|
894
|
-
// Run your queries
|
|
895
849
|
await prisma.user.findMany({ where: { status: 'ACTIVE' } })
|
|
896
850
|
await prisma.post.findMany({ include: { author: true } })
|
|
897
851
|
|
|
898
|
-
// Analyze
|
|
899
852
|
console.table(queries)
|
|
900
853
|
```
|
|
901
854
|
|
|
@@ -906,13 +859,10 @@ git clone https://github.com/dee-see/prisma-sql
|
|
|
906
859
|
cd prisma-sql
|
|
907
860
|
npm install
|
|
908
861
|
|
|
909
|
-
# Setup test database
|
|
910
862
|
npx prisma db push
|
|
911
863
|
|
|
912
|
-
# Run PostgreSQL benchmarks
|
|
913
864
|
DATABASE_URL="postgresql://..." npm run test:e2e:postgres
|
|
914
865
|
|
|
915
|
-
# Run SQLite benchmarks
|
|
916
866
|
npm run test:e2e:sqlite
|
|
917
867
|
```
|
|
918
868
|
|