Files
homaroma/PRISMA7_GUIDE.md
T
2026-10-01 05:49:58 +07:00

254 lines
8.0 KiB
Markdown

# Prisma 7 — คู่มือการเชื่อมต่อและทำ Seed (ไม่งงอีกต่อไป)
> **Platform engineering guide:** Any HomAroma seed data in this guide is reference-tenant data. Validate the target tenant database and seed strategy before use.
xx
> **สำคัญมาก:** Prisma 7 เปลี่ยนวิธีการเชื่อมต่อฐานข้อมูลอย่างพื้นฐาน
> ถ้าเคยใช้ Prisma 4, 5, หรือ 6 มาก่อน — ของเก่าพวกนั้น **ใช้ไม่ได้อีกแล้ว**
---
## 1. สิ่งที่เปลี่ยนไปจาก Prisma 6fdss → Prisma 7
| เรื่อง | Prisma 5/6 (เก่า) | Prisma 7 (ใหม่) |
|---|---|---|
| `DATABASE_URL` ใน `schema.prisma` | ✅ ใช้ได้ | ❌ ใช้ไม่ได้ |
| `new PrismaClient()` ไม่มี options | ✅ อ่าน `.env` เอง | ❌ Error ทันที |
| Config ฐานข้อมูล | อยู่ใน `schema.prisma` | ย้ายไปที่ `prisma.config.ts` |
| วิธีเชื่อมต่อ | ผ่าน URL ใน `.env` | ผ่าน **Driver Adapter** |
---
## 2. โครงสร้างไฟล์ที่ถูกต้องสำหรับ Prisma 7
```
apps/backend/
├── prisma/
│ ├── schema.prisma # Models เท่านั้น — ห้ามใส่ url ใน datasource
│ ├── seed.js # Seed file (ใช้ .js ไม่ใช่ .ts เพื่อหลีกเลี่ยง ts-node issues)
│ └── migrations/ # Migration files
├── prisma.config.ts # ← จุดตั้งค่าหลักของ Prisma 7
├── .env # DATABASE_URL อยู่ที่นี่
└── package.json
```
---
## 3. `schema.prisma` — ห้ามใส่ `url`
```prisma
// ✅ CORRECT — Prisma 7
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
// ❌ ห้ามใส่บรรทัดนี้: url = env("DATABASE_URL")
}
model Scent {
id Int @id @default(autoincrement())
name String
size String?
sku String? @unique
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
```
---
## 4. `prisma.config.ts` — ไฟล์หลักของ Prisma 7
```typescript
import "dotenv/config";
import { defineConfig } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: "node prisma/seed.js", // ← ชี้ไปที่ seed.js (ไม่ใช่ seed.ts)
},
datasource: {
url: process.env["DATABASE_URL"], // ← URL อยู่ที่นี่แทน schema.prisma
},
});
```
---
## 5. `seed.js` — Template ที่ใช้งานได้จริง
> **ทำไมใช้ `.js` ไม่ใช่ `.ts`:** `ts-node` ใน environment นี้ไม่แสดง output ทำให้ debug ยาก ใช้ `.js` แทนเพื่อความเสถียร
```javascript
// seed.js — CommonJS format
const path = require('path');
// โหลด .env ก่อนทุกอย่าง
require('dotenv').config({ path: path.join(__dirname, '../.env') });
const { PrismaClient } = require('@prisma/client');
const { PrismaPg } = require('@prisma/adapter-pg'); // ← จำเป็นสำหรับ Prisma 7
// ✅ วิธีเดียวที่ถูกต้องใน Prisma 7 — ต้องส่ง adapter เข้าไป
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL });
const prisma = new PrismaClient({ adapter });
const data = [
// ใส่ข้อมูลที่ต้องการ seed ที่นี่
{ name: 'ตัวอย่าง', size: '120ml', sku: '120-ตัวอย่าง-120ml' },
];
async function main() {
process.stdout.write('🚀 Starting seeding...\n');
for (const item of data) {
await prisma.scent.upsert({
where: { sku: item.sku }, // ← ใช้ unique field
update: {}, // ← ถ้ามีอยู่แล้วไม่ต้อง update
create: item,
});
process.stdout.write(`✅ ${item.name} (${item.size})\n`);
}
process.stdout.write(`✨ Done! Total: ${data.length} records\n`);
}
main()
.catch((e) => {
process.stderr.write(`❌ Error: ${e.message}\n`);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});
```
---
## 6. Packages ที่ต้อง Install
```bash
# Dependencies หลัก
npm i @prisma/client @prisma/adapter-pg pg
# Dev dependencies
npm i -D prisma dotenv
```
> **ต่างจากเดิม:** Prisma 7 ต้องการ `@prisma/adapter-pg` ด้วย — ขาดไม่ได้!
---
## 7. วิธีรัน Seed
```bash
# วิธีที่ 1: รันตรงๆ (แนะนำสำหรับ debug)
cd apps/backend
node prisma/seed.js
# วิธีที่ 2: ผ่าน Prisma CLI (ต้องตั้งค่าใน prisma.config.ts แล้ว)
cd apps/backend
npx prisma db seed
```
---
## 8. Error ที่พบบ่อยและวิธีแก้
### ❌ Error: `url is no longer supported in schema files`
```
The datasource property `url` is no longer supported in schema files.
```
**แก้:** ลบ `url = env("DATABASE_URL")` ออกจาก `schema.prisma`
**ย้ายไปใส่:** `prisma.config.ts` → `datasource.url`
---
### ❌ Error: `PrismaClient needs to be constructed with a non-empty, valid PrismaClientOptions`
```
PrismaClientInitializationError: `PrismaClient` needs to be constructed with...
```
**แก้:** ต้องส่ง `adapter` เข้าไปใน constructor เสมอ
```javascript
// ❌ ผิด
const prisma = new PrismaClient();
// ✅ ถูก
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL });
const prisma = new PrismaClient({ adapter });
```
---
### ❌ Error: `Unknown property datasourceUrl provided to PrismaClient constructor`
```
PrismaClientConstructorValidationError: Unknown property datasourceUrl...
```
**แก้:** Prisma 7 ไม่รับ `datasourceUrl` แล้ว ต้องใช้ `adapter` แทน
```javascript
// ❌ ผิด (เคยใช้ได้ใน Prisma 6)
const prisma = new PrismaClient({ datasourceUrl: process.env.DATABASE_URL });
// ✅ ถูก
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL });
const prisma = new PrismaClient({ adapter });
```
---
### ❌ Error: `⚠️ No seed command configured`
```
⚠️ No seed command configured
```
**แก้:** เพิ่ม `seed` ใน `prisma.config.ts` (ไม่ใช่แค่ใน `package.json` อีกต่อไป)
```typescript
migrations: {
path: "prisma/migrations",
seed: "node prisma/seed.js", // ← ต้องมีบรรทัดนี้
},
```
---
## 9. Checklist ก่อนทำ Seed ทุกครั้ง
```
□ 1. schema.prisma → datasource ไม่มี url
□ 2. prisma.config.ts → datasource.url ตั้งค่าไว้
□ 3. prisma.config.ts → migrations.seed ชี้ถูก
□ 4. .env มี DATABASE_URL ครบถ้วน
□ 5. ติดตั้ง @prisma/adapter-pg และ pg แล้ว
□ 6. seed.js ใช้ PrismaPg adapter ในการสร้าง PrismaClient
□ 7. รัน npx prisma db push หรือ migrate ก่อน seed
□ 8. รัน node prisma/seed.js เพื่อ seed
```
---
## 10. สรุปภาพรวม Flow
```
.env (DATABASE_URL)
↓
prisma.config.ts (datasource.url)
↓ npx prisma db push/migrate
schema.prisma (Models) → Database Tables
↓ node prisma/seed.js
seed.js (PrismaPg adapter + PrismaClient) → Insert data → DB
```