252 lines
7.8 KiB
Markdown
252 lines
7.8 KiB
Markdown
# Prisma 7 — คู่มือการเชื่อมต่อและทำ Seed (ไม่งงอีกต่อไป)
|
|
|
|
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
|
|
```
|