ãTypeScript/ORMãPrisma Tipséð

uuid v7ã®æå®æ¹æ³
model User {
id String @id @default(uuid()) // defaults to 4
name String
}
model User {
id String @id @default(uuid(4)) // same as above, but explicit
name String
}
model User {
id String @id @default(uuid(7)) // will use UUIDv7 instead of UUIDv4
name String
}

Prismaã§ãªã¬ãŒã·ã§ã³ãå®çŸ©ãã
1察å€, 1察1
/**
* User Entity
*/
model User {
userId String @id @default(uuid(7)) // UUID v7ãæå®ããã
email String @unique
name String
createdAt DateTime @default(now())
messages Message[] // User:Message = 1:N ã®é¢ä¿ãæã€ã
userProfile UserProfile? // User:UserProfile = 1:1 ã®é¢ä¿ãæã€ã(Optional)
}
// ã¡ãã»ãŒãžã®éä¿¡è
ãç¹å®ããããã®åæå
enum Sender {
USER
AI
}
/**
* Message Entity
- ã¡ãã»ãŒãžã®éä¿¡è
ãç¹å®ããããã«ãuserIdãå€éšããŒãšããŠæã€ã
- User:Message = 1:N ã®é¢ä¿ãæã€ã
*/
model Message {
messageId String @id @default(uuid(7)) // UUID v7ãæå®ããã
userId String
user User @relation(fields: [userId], references: [userId])
sender Sender // ã¡ãã»ãŒãžã®éä¿¡è
ãç¹å®ããããã®åæå
content String
createdAt DateTime @default(now())
}
/**
* UserProfile Entity
- ãŠãŒã¶ãŒã®åºæ¬æ
å ±ãåéãããã©ãŒã ã®ãšã³ãã£ãã£ã
- User:UserInfoForm = 1:1 ã®é¢ä¿ãæã€ã
*/
model UserProfile {
userProfileId String @id @default(uuid(7))
userId String @unique // User:UserProfile = 1:1 ã®é¢ä¿ãæã€ã
user User @relation(fields: [userId], references: [userId])
createdAt DateTime @default(now())
}

Prismaã§Enumãå®çŸ©ãã
enum Role {
USER
ADMIN
}
model User {
id Int @id @default(autoincrement())
name String
role Role @default(USER)
}

Prismaã§ããããããéð

Prismaã§not nullð
Prismaã§ã¯ãã¹ããŒããã¡ã€ã«å
ã§ãã£ãŒã«ãã®åãå®çŸ©ããéãåã®åŸãã«çå笊ïŒ?
ïŒãä»ããªããã°ããã®ãã£ãŒã«ãã¯å¿
é ïŒNOT NULLïŒãšããŠæ±ãããŸãã
ã€ãŸããæ¬¡ã®ããã«å®çŸ©ããã ãã§ NOT NULL ã®ã«ã©ã ãäœæãããŸãã
model User {
id Int @id @default(autoincrement())
name String // NOT NULL ã«ã©ã
}
éã«ãname String?
ãšããã°ããã®ã«ã©ã ã¯NULLã蚱容ããããã«ãªããŸãã
ãŸããæ¢åããŒãã«ã«æ°ããªå¿ é ã«ã©ã ïŒNOT NULLïŒã远å ããå Žåãæ¢åã®ã¬ã³ãŒãã«å¯ŸããŠå€ãèšå®ãããŠããªããšãã€ã°ã¬ãŒã·ã§ã³ãšã©ãŒãšãªããããããã©ã«ãå€ãèšå®ããããçæããããã€ã°ã¬ãŒã·ã§ã³SQLãç·šéããŠå¯Ÿå¿ããå¿ èŠããããŸãã

Prismaã§Indexãä»äžããð
Prismaã§ã¯ãããŒã¿ããŒã¹ã®ããã©ãŒãã³ã¹ãåäžãããããã«ã€ã³ããã¯ã¹ãç°¡åã«èšå®ããããšãã§ããŸããã€ã³ããã¯ã¹ã¯ã¯ãšãªã®å®è¡é床ãåäžãããéèŠãªæ©èœã§ãã
åºæ¬çãªã€ã³ããã¯ã¹ã®ä»äžæ¹æ³
Prismaã§ã€ã³ããã¯ã¹ãèšå®ããã«ã¯ãäž»ã«@@index
屿§ã䜿çšããŸãããã®å±æ§ã¯ã¢ãã«ã¬ãã«ã§é©çšãããåäžã«ã©ã ãšè€æ°ã«ã©ã ã®äž¡æ¹ã®ã€ã³ããã¯ã¹ããµããŒãããŠããŸã[1][3]ã
åäžã«ã©ã ã®ã€ã³ããã¯ã¹
model Post {
id Int @id @default(autoincrement())
title String
content String?
@@index([title])
}
è€æ°ã«ã©ã ã®ã€ã³ããã¯ã¹ïŒè€åã€ã³ããã¯ã¹ïŒ
model Post {
id Int @id @default(autoincrement())
title String
content String?
@@index([title, content])
}
ãã®äŸã§ã¯ãtitle
ãšcontent
ãã£ãŒã«ãã«å¯ŸããŠè€åã€ã³ããã¯ã¹ãäœæããŠããŸã[1][3][4]ã
ã€ã³ããã¯ã¹å±æ§ã®èšå®ãªãã·ã§ã³
@@index
屿§ã«ã¯ä»¥äžã®ãããªåŒæ°ãæå®ã§ããŸã[1]:
- fields: ã€ã³ããã¯ã¹å¯Ÿè±¡ã®ãã£ãŒã«ããæå®ããå¿ é åŒæ°
- name: ã€ã³ããã¯ã¹ã®ååãèšå®ïŒçç¥å¯èœïŒ
- map: ååãæç€ºçã«æå®ãããŠããªãå Žåã®ã€ã³ããã¯ã¹åã®åœåèŠåãå®çŸ©
- length: StringåãšBytesåã®å€ã®ã€ã³ããã¯ã¹ãµã€ãºãæå®ïŒMySQLã®ã¿ïŒ
- sort: ã€ã³ããã¯ã¹ãšã³ããªã®ä¿åé åºãæå®ïŒAsc/DescïŒ
- type: PostgreSQLã§ã®ã¿äœ¿çšå¯èœã§ãBTree以å€ã®ã¢ã¯ã»ã¹ã¡ãœããããµããŒã
- clustered: ã€ã³ããã¯ã¹ãã¯ã©ã¹ã¿ãŒåãããŠãããã©ãããèšå®ïŒSQL Serverã®ã¿ïŒ
- ops: PostgreSQLã§ã®ã¿ãµããŒããããç¹å®ã®ã€ã³ããã¯ã¹ã¿ã€ãã®æŒç®åãå®çŸ©
ååä»ãã€ã³ããã¯ã¹ã®äŸ
model User {
id Int @id @default(autoincrement())
email String
phone String
@@index([email, phone], name: "email_phone")
}
ãã®äŸã§ã¯ãemail
ãšphone
ãã£ãŒã«ãã«å¯ŸããŠ"email_phone"ãšããååã®è€åã€ã³ããã¯ã¹ãäœæããŠããŸã[4]ã
ãŠããŒã¯å¶çŽãšã€ã³ããã¯ã¹
SQLããŒã¿ããŒã¹ã§ã¯ããŠããŒã¯å¶çŽãå®çŸ©ãããšã察å¿ãããŠããŒã¯ã€ã³ããã¯ã¹ãèªåçã«äœæãããŸã[1]ãã€ãŸãã@unique
屿§ãä»äžãããã«ã©ã ã«ã¯èªåçã«ã€ã³ããã¯ã¹ãå²ãåœãŠãããŸãã
model User {
id Int @id @default(autoincrement())
email String @unique
phone String
}
è€åãŠããŒã¯å¶çŽãèšå®ããå Žåã¯ã以äžã®ããã«èšè¿°ããŸãïŒ
model User {
id Int @id @default(autoincrement())
email String
phone String
@@unique([email, phone], name: "unique_email_phone")
}
ã€ã³ããã¯ã¹ã®é©çš
ã¹ããŒãã«ã€ã³ããã¯ã¹ã远å ããåŸã¯ããã€ã°ã¬ãŒã·ã§ã³ãå®è¡ããŠå®éã®ããŒã¿ããŒã¹ã«åæ ãããå¿ èŠããããŸã[1][8]ïŒ
# npm
npx prisma migrate dev --name add_some_indexes
# pnpm
pnpm dlx prisma migrate dev --name add_some_indexes
ãã®ã³ãã³ããå®è¡ãããšãPrismaã¯æ°ãããã€ã°ã¬ãŒã·ã§ã³ãã¡ã€ã«ãäœæããããã«ã€ã³ããã¯ã¹äœæã®SQLã¹ã¯ãªãããå«ãŸããŸã[1]ã
ãŸãšã
Prismaã§ã€ã³ããã¯ã¹ãä»äžããã«ã¯ãäž»ã«@@index
屿§ã䜿çšããŸãã
åäžã«ã©ã ãšè€æ°ã«ã©ã ã®äž¡æ¹ã®ã€ã³ããã¯ã¹ããµããŒãããŠãããæ§ã
ãªèšå®ãªãã·ã§ã³ãéããŠããŒã¿ããŒã¹åºæã®æ©èœã掻çšã§ããŸãã
ã€ã³ããã¯ã¹ãé©åã«èšå®ããããšã§ãã¯ãšãªã®ããã©ãŒãã³ã¹ã倧å¹
ã«åäžãããããšãã§ããŸãã

Prismaã®æåååã®çš®é¡
Prismaã§ã¯ãæååããŒã¿ãæ±ãããã®åãšããŠäž»ã«ä»¥äžã®çš®é¡ããããŸãã
åºæ¬çãªæååå
Prismaã®åºæ¬çãªæåååã¯String
ã§ããããã¯ããŒã¿ããŒã¹ã«ãã£ãŠç°ãªãåã«ãããã³ã°ãããŸã[8]ãäŸãã°ïŒ
- PostgreSQLã§ã¯
text
åã«ãããã³ã°ãããŸã[7][8] - MySQLã§ã¯
varchar(191)
åã«ãããã³ã°ãããŸã[17]
æåååã®ããªãšãŒã·ã§ã³
ããŒã¿ããŒã¹åºæã®åãæå®ãããå Žåã¯ã@db
屿§ã䜿çšããŠä»¥äžã®ããã«æå®ã§ããŸãïŒ
PostgreSQLã®å Žå
-
@db.Text
- 倧éã®ããã¹ããæ ŒçŽã§ããåïŒæå€§1GBãŸã§ïŒ[5] -
@db.VarChar(n)
- å¯å€é·ã®æååïŒäŸïŒ@db.VarChar(255)
ïŒ[5]
ãã®ä»ã®ããŒã¿ããŒã¹åºæã®å
ããŒã¿ããŒã¹ã«ãã£ãŠãããŸããŸãªæåååããµããŒãããŠããŸã[15][16]ã
æååé åå
Prismaã§ã¯ãããŒã¿ããŒã¹ããã€ãã£ãã«ãµããŒãããŠããå Žåãæååã®é åã䜿çšã§ããŸã[12]ïŒ
tags String[]
æåååã®å±æ§
æåååã«ã¯ä»¥äžã®ãããªå±æ§ãä»ããããšãã§ããŸãïŒ
-
@id
- äž»ããŒãšããŠäœ¿çš[8] -
@unique
- äžæã®å€ã匷å¶[4] -
@default("å€")
- ããã©ã«ãå€ãèšå®[8] -
?
- ãªãã·ã§ãã«ïŒnull蚱容ïŒã衚ã[10]
äŸ
model User {
id String @id @default(cuid())
name String? // ãªãã·ã§ãã«ãªæåå
email String @unique
bio String @db.Text // 倧éã®ããã¹ã
username String @db.VarChar(50) // æå€§50æå
tags String[] // æååã®é
åïŒãµããŒããããŠããå ŽåïŒ
}
Prismaã§ã¯ããããã®åã䜿ãåããããšã§ãããŒã¿ããŒã¹ã®ç¹æ§ã掻ãããªããåå®å šãªã¢ããªã±ãŒã·ã§ã³éçºãå¯èœã«ãªããŸã[6][7]ã

Prismaã§ãColumnã®é åºãæå®ããã«ã¯ïŒ
Prisma ORMã§ã¯ åã®äžŠã³é ãå¶åŸ¡ããå
¬åŒæ§æã¯ãŸã æäŸãããŠãããã
çæããã DDL ã¯ãæåã«ããŒãã«ãäœæãããšãã®å®çŸ©é ãããæ¢å DB ã®é åº (db pull / introspection ã®çµæ)ãã«åŸããŸãã
å®è¡æã®ã¯ãšãªã¯åé ã«äŸåããªããããçŸç¶ã¯ èŠãç®ã®äžŠã³ãå€ãããå Žåã ãæäœæ¥ã§ DDL ãç·šéããã®ãå®ç³ã§ãã
1-1 Prisma ã§é åºãæå®ã§ããªãçç±
- Prisma ã¹ããŒãã«ã¯
@map
ãªã©ã®ãããã³ã°å±æ§ã¯ãããŸãã ããã®åãä»ã®åã®ååŸã«çœ®ããããã®å±æ§ã¯ååšããŸãã ([Stack Overflow][1], [Reddit][2]) - å ¬åŒ Issue ã§ããDB åŽã®åé ããœãŒã¹ãªããã¥ã«ãŒã¹ãšããã¹ããŒãã®äžŠã³æ¿ãã¯è¡ããªãæ¹éããšæèšãããŠããŸã ([GitHub][3])
çµè«: Prisma ã ãã§åé ãåºå®ããããšã¯ã§ããŸããã
1-2 ã©ãããŠãé åºãå€ãããå Žåã®ã¯ãŒã¯ãããŒ
-
ãã©ãããã€ã°ã¬ãŒã·ã§ã³ãçæ
npx prisma migrate dev --create-only
-
çæããã
migration.sql
ãéããPostgreSQL ãªãALTER TABLE "User" ALTER COLUMN "email" DROP DEFAULT, ALTER COLUMN "email" SET DATA TYPE varchar(320), -- â ç¬èªã«è¿œèš ALTER TABLE "User" ALTER COLUMN "email" SET POSITION 3; -- â»MySQL ã® AFTER/BODY ãªã©ã«çœ®ãæã
-
ç·šéåŸã«é©çš
npx prisma migrate dev
Prisma ããã¥ã¡ã³ãã«ããé åºå€æŽãªã© Prisma ãèªåçæããªã DDL ã¯æã§æžããŠããé©çšãããäŸã瀺ãããŠããŸã ([Prisma][4])
泚æ: Postgres ã«ã¯
ALTER COLUMN ⊠POSITION
ãç¡ãã®ã§ãå®éã«ã¯ãæ°èŠããŒãã«ãäœã£ãŠã³ããŒâãªããŒã ããªã©ãè¡ããŸããåé ã¯ã¢ããªåäœã«åœ±é¿ããªããããå¯èªæ§ã«æããªããã°ãã€ã°ã¬ãŒã·ã§ã³ç·šéã¯äžèŠã§ãã
ãŸãšã
- åé 㯠Prisma ã§ã¯æå®äžå¯ã
- å¯èªæ§ã®ããã«äžŠã³ãå€ãããå Žå㯠æåã§ SQL ãç·šéãããããããŸããã
- ããã©ãããã€ã°ã¬ãŒã·ã§ã³ãçæããŠæãå ãããã¯ãŒã¯ãããŒãèŠããŠãããšãPrisma ããŸã 察å¿ããŠããªã DB æ©èœãå®å šã«åã蟌ããŸãã

Columnã«ã³ã¡ã³ãã远å ããã«ã¯ïŒ
åãããŒãã«ã«ã³ã¡ã³ããä»ããããã®ä»çµã¿ã¯çšæãããŠããã/// ããã¥ã¡ã³ããŒã·ã§ã³ã³ã¡ã³ããšããã€ãã®ã¯ãŒã¯ãããŒãçµã¿åããããš DB ã¬ãã«ã® COMMENT ON å¥ãŸã§çæã§ããŸãã
///
ã§ããã¥ã¡ã³ããŒã·ã§ã³ã³ã¡ã³ããä»äžã§ããïŒ
1. Prisma ã¹ããŒãã§ã¯ ///
ã§å§ãŸãã³ã¡ã³ãã AST ã«åã蟌ã¿ãå€éšããŒã«ãååŸã§ããããã«ãªã£ãŠããŸã ([Prisma][5])
/// ãŠãŒã¶ãŒæ
å ±
model User {
id Int @id @default(autoincrement())
/// ã¡ãŒã«ã¢ãã¬ã¹ (RFC 320chars)
email String @db.VarChar(320)
}
COMMENT ON
ãèªåçæããæ¹æ³
2. DB ã¬ãã«ã® æ¹æ³ | ç¹åŸŽ | å®è£ æé |
---|---|---|
å
¬åŒ previewFeature comments (Prisma 5 ç³»ã§ç»å Ž) |
prisma migrate dev ã§ COMMENT ON TABLE/COLUMN ãå
¥ã£ã SQL ãåã |
prisma<br>generator client {<br> provider = "prisma-client-js"<br> previewFeatures = ["comments"]<br>}<br> â éåžžã©ãã migrate |
ã³ãã¥ããã£è£œ Generator prisma-db-comments-generator
|
æ¢åãããžã§ã¯ãã«ãåŸä»ããããã | 1) npm i -D @onozaty/prisma-db-comments-generator 2) schema.prisma ã«prisma<br>generator comments {<br> provider = "prisma-db-comments-generator"<br>}<br> 3) npx prisma generate ã§ migrations/YYYY..._update_comments/migration.sql ãçæããã ([GitHub][6]) |
ææžãã§è¿œèš | æãã·ã³ãã« | 1) --create-only ã§ãã©ãããåã2) çæ SQL ã®æ«å°Ÿã« sql<br>COMMENT ON COLUMN "User"."email" IS 'ã¡ãŒã«ã¢ãã¬ã¹ (320 æå)';<br> 3) migrate dev ã§é©çš ([Nico's Blog][7]) |
3. ã¢ãã«ã³ã¡ã³ãã察å¿
///
ãã¢ãã«ã®å
é ã«ã€ããŠããã°ãäžèšã®ãããã®æ¹æ³ã§ãããŒãã«ã³ã¡ã³ããšããŠä»äžãããŸã ([GitHub][8], [GitHub][8])
ãŸãšã
-
åã³ã¡ã³ãã¯
///
ãš previewFeaturecomments
ã§å ¬åŒã«ãµããŒãã - æ¢åãããžã§ã¯ãã§ã¯ Generator ãææžã远èšãå®çšçã§ãã