[Node.js] Prisma CRUD ๊ตฌํํด ๋ณด๊ธฐ (feat Prisma Studio)
์๋ ํ์ธ์. Foma ์ ๋๋ค.
์ ๋ฒ ๊ธ์ Prisma์ ๊ดํ ๋ด์ฉ๊ณผ ์ฌ์ฉํด์ผ ํ๋ ์ด์ ์ ๋ํด์ ์ ๋ฆฌํ๋๋ฐ์.
(ํน์ ์๋ณด์ ๋ถ๋ค์ ์ฌ๊ธฐ ์์ ๋ณด์๋ฉด ๋ฉ๋๋ค!)
์ค๋์ Prisma๋ฅผ ์ด์ฉํ์ฌ CRUD๋ฅผ ๊ตฌํํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
๋ฐ๋ก ์์ํ ๊ฒ์~
Init Prisma
๋น ํด๋๋ฅผ ๋ง๋ค๊ณ npm์ ์ด๊ธฐํ ํด์ค๋๋ค.
npm init -y
๊ทธ ๋ค์ ํ์ ์คํฌ๋ฆฝํธ prisma์ ts-node, @types/node๋ฅผ ์ค์นํด ์ค๋๋ค.
npm install prisma @prisma/client typescript ts-node @types/node --save-dev
๊ทธ ๋ค์ prisma๋ฅผ ์๋ ๋ช ๋ น์ด๋ก ์ด๊ธฐํ ํด์ค๋๋ค.
npx prisma init
์๋์ ๊ฐ์ด ์๋์ผ๋ก prisma ํด๋์ env ํ์ผ์ด ์์ฑ๋ ๊ฑฐ์์.
Set a environment
.env ํ์ผ๋ก ์ด๋ํ์ ์ ์๋์ ๊ฐ์ด DB ์ ๋ณด๋ฅผ ์ ๋ ฅํด ์ค๋๋ค.
DATABASE_URL="๋๋น์ข
๋ฅ://์ ์ ์ด๋ฆ:ํจ์ค์๋@localhost:ํฌํธ๋ฒํธ/๋๋น์ด๋ฆ"
Set a schema.prisma
schema.prisma ํ์ผ๋ก ์ด๋ํด์ client๋ฅผ ์์ฑํด ์ค๋๋ค.
generator client {
provider = "prisma-client-js"
}
db ๋ฐ์ดํฐ ์์ค๋ฅผ .env ํ์ผ์ ์์ฑํ ๋๋น ์ข ๋ฅ์ DATABASE_URL์ ์ ๋ ฅํด ์ค๋๋ค.
datasource db {
provider = "๋๋น์ข
๋ฅ"
url = env("DATABASE_URL")
}
๊ทธ ๋ค์ ํ ์ด๋ธ์ ์ํ๋ ๋ฐ์ดํฐ ๋ชจ๋ธ์ ์ ์ํด ์ค๋๋ค.
model User {
id Int @id @default(autoincrement())
name String @unique @db.VarChar(255)
age Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
Init User table
ํ ์ด๋ธ์ ๋ง์ด๊ทธ๋ ์ดํธ๋ฅผ ์งํํด ์ค๋๋ค.
npx prisma migrate dev --name ํ
์ด๋ธ์ด๋ฆ_table_init
์๋์ ๊ฐ์ด migrations ํด๋๊ฐ ์๊ธฐ๊ณ ํด๋น schema ํ์ผ์์ ์ ์ํ ๋ชจ๋ธ์ ๋ง๋๋ sql๋ฌธ์ด ์์ฑ๋์ด ์๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
MySQL ์ํฌ๋ฒค์น๋ก ๊ฐ์ ํ์ธํ๋ฉด ํด๋น ๋๋น์ ํ ์ด๋ธ์ด ์์ฑ๋๊ณ ์ค์ ํ ์ปฌ๋ผ๋ค์ด ์๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
์๋ ๋ช ๋ น์ด๋ฅผ ํฐ๋ฏธ๋์ ์คํํ๋ฉด migration ํ์ผ์ด ์์ฑ๋์ง ์๊ณ DB๊ฐ ์์ฑํด์ค ๋ชจ๋ธ๋๋ก ์ ๋ฐ์ดํธ ๋ฉ๋๋ค.
npx prisma db push
Create
์ฌ๋ฌ ๋ฐ์ดํฐ ํ ๋ฒ์ ์์ฑํ๊ธฐ
prisma.๋ชจ๋ธ์ด๋ฆ.createMany ๋ฉ์๋์ ์ค๋ธ์ ํธ ํ์์ผ๋ก ๋ ์ฌ๋ฌ data๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ํ ๋ฒ์ ์ฌ๋ฌ ๋ฐ์ดํฐ๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
skipDuplicates๋ฅผ true๋ก ํด์ฃผ๋ฉด ์ค๋ณต๋ ๋ฐ์ดํฐ๊ฐ ์์ฑ๋๋ ๊ฒ์ ๋ง์ ์ ์์ต๋๋ค.
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
async function main() {
try {
const data = [
{ name: "Kalid", age: 27 },
{ name: "fomagran", age: 28 },
{ name: "Young", age: 26 },
{ name: "Kalid", age: 27 },
];
const res = await prisma.user.createMany({
data,
skipDuplicates:true
});
console.log("Created a user sucessfully", res);
} catch (err) {
console.log("Create a user Error:", err);
} finally {
async () => {
await prisma.$disconnect();
};
}
}
main();
๊ทธ ๋ค์ ts-node๋ก ํด๋น ํ์ผ์ด ์๋ ๊ฒฝ๋ก๋ฅผ ์ ๋ ฅํด์ฃผ๋ฉด ์๋์ ๊ฐ์ด ์ฝ๋๊ฐ ์คํ ๋ฉ๋๋ค.
1๊ฐ ๋ฐ์ดํฐ๋ง ์ถ๊ฐํ๊ธฐ
prisma.๋ชจ๋ธ์ด๋ฆ.createMany ๋ถ๋ถ์ data ํ๋กํผํฐ์ ํด๋น ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด์ค๋๋ค.
const user = { name: "Kendrick", age: 26 };
const res = await prisma.user.createMany({
data:user,
});
...
Read
๋ชจ๋ ๋ฐ์ดํฐ ์ฝ๊ธฐ
prisma.๋ชจ๋ธ์ด๋ฆ.findMany()๋ฅผ ์ด์ฉํ๋ฉด ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ์ ์์ต๋๋ค.
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
async function main() {
try {
const res = await prisma.user.findMany();
console.log("All users: ", res);
} catch (err) {
console.log("Read a user Error:", err);
} finally {
async () => {
await prisma.$disconnect();
};
}
}
main();
์์์ ์ถ๊ฐํ ๋ฐ์ดํฐ๋ค์ด ์๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
์กฐ๊ฑด์ ๊ฑธ์ด ํน์ ๋ฐ์ดํฐ๋ง ๋ถ๋ฌ์ค๊ธฐ
age๊ฐ 27๋ณด๋ค ํฌ๊ฑฐ๋ ๊ฐ์ ์ ์ ๋ฅผ ๋ถ๋ฌ ์ค๊ฒ ์ต๋๋ค. (gte => greater than or equal)
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
async function main() {
try {
const res = await prisma.user.findMany({
where: {
age: {
gte: 27,
},
},
});
console.log("The age is greater than or equal 27 users : ", res);
} catch (err) {
console.log("Read a user Error:", err);
} finally {
async () => {
await prisma.$disconnect();
};
}
}
main();
์๋์ ๊ฐ์ด age๊ฐ 27๋ณด๋ค ํฌ๊ฑฐ๋ ๊ฐ์ ์ ์ ๊ฐ ์ถ๋ ฅ๋ฉ๋๋ค.
Update
prisma.๋ชจ๋ธ์ด๋ฆ.updateMany๋ฅผ ์ด์ฉํ์ฌ age๊ฐ 28์ธ ์ฌ๋์ ์ด๋ฆ์ oldman์ผ๋ก ๋ฐ๊ฟ ๋ณด๊ฒ ์ต๋๋ค.
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
async function main() {
try {
const res = await prisma.user.updateMany({
where: {
age: {
equals: 28,
},
},
data: {
name: "oldman",
},
});
console.log("Updated a user sucessfully", res);
} catch (err) {
console.log("Update a user Error:", err);
} finally {
async () => {
await prisma.$disconnect();
};
}
}
main();
์๋์ ๊ฐ์ด ๋์ด๊ฐ 28์ธ ์ ์ ์ ์ด๋ฆ์ด oldman์ผ๋ก ๋ฐ๊ปด ์๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
Delete
prisma.๋ชจ๋ธ์ด๋ฆ.deleteMany๋ก ๋์ด๊ฐ 28์ธ ์ฌ๋์ ์ญ์ ํด ๋ณด๊ฒ ์ต๋๋ค.
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
async function main() {
try {
const res = await prisma.user.deleteMany({
where: {
age: {
equals: 28,
},
},
});
console.log("Deleted a user sucessfully", res);
} catch (err) {
console.log("Delete a user Error:", err);
} finally {
async () => {
await prisma.$disconnect();
};
}
}
main();
์๋์ ๊ฐ์ด ๋์ด๊ฐ 28์ธ ์ฌ๋์ด ์ญ์ ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
Prisma Studio
์ ๊ณผ์ ์ ๋์ฑ ์ฝ๊ฒ ํ ์ ์๋ ๋ฐฉ๋ฒ์ด ์๋๋ฐ์.
๋ฐ๋ก Prisma Studio๋ฅผ ์ด์ฉํ๋ ๊ฒ ์ ๋๋ค.
์๋์ ๊ฐ์ด ํ๋ฆฌ์ฆ๋ง ์คํ๋์ค๋ฅผ ์คํ์์ผ ์ค๋๋ค.
npx prisma studio
๊ทธ๋ฌ๋ฉด http:/localhost:5555 ์ฐฝ์ด ์๋์ผ๋ก ๋จ๊ฒ ๋๋๋ฐ์.
๋ฐ๋ก ์๋์ ๊ฐ์ด ์์์ ์์ฑํ ํ ์ด๋ธ๋ค์ด ๋ณด์ด๊ฒ ๋ฉ๋๋ค.
ํด๋น ํ ์ด๋ธ์ ํด๋ฆญํ๋ฉด ์์ฑํ๋ ๋ฐ์ดํฐ๋ค์ ํ์ธํ ์ ์์ต๋๋ค.
๋ก์ฐ๋ฅผ ์ ํํ์ฌ ์ญ์ ๋๋ ์์ฑํ ์๋ ์์ผ๋ฉฐ,
๋ํ ์ํ๋ ์ปฌ๋ผ์ ๋๋ธ ํด๋ฆญํ์ฌ ์์ ํ ์๋ ์์ต๋๋ค.
์ ์คํ๋์ค์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊พธ๊ณ ๋์ MySQL ์ํฌ๋ฒค์น๋ก ์ด๋ํด ๋ฐ์ดํฐ๋ฅผ ํ์ธํด ๋ณด๋ฉด ์ค์๊ฐ์ผ๋ก ๋ฐ์ดํฐ๊ฐ ๋ฐ๋์ด ์๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
๋๋ ์
์ด์ Sequelize, TypeORM์ ๋นํด ํจ์ฌ ์ง๊ด์ ์ด๊ณ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๋ ๋ ๊ฐํธํ๋ค.
์ด์ ๊ธ์์ Prisma๊ฐ ๊ฐ๋ฐ์์ ์์ฐ์ฑ์ ์ฐ์ ๋ชฉํ๋ก ํ๋ค๊ณ ํ๋ ๊ฒ์ด ์ด๋ค ์๋ฏธ์ธ์ง ์ ๊ฒ ๊ฐ๋ค.
ํนํ Prisma Studio๋ฅผ ํตํด์ ๋ฐ์ดํฐ๋ฅผ ์กฐ์ํ๋ ๊ฒ์ ์ ๋ง ํธ๋ฆฌํ๊ณ ์์ฐ์ ์ธ ์ธก๋ฉด์์ ์์ฒญ ํจ์จ์ ์ธ ๊ฒ ๊ฐ๋ค.