JavaScript/JS백엔드
Prisma 기본
염두리안
2025. 1. 1. 21:55
728x90
반응형
Prisma 초기화
npx prisma init --datasource-provider postgresql
.env 파일에서windows의 경우 [postgres:password]로 변경하고, mydb를 생성할 db 이름 입력
DATABASE_URL="postgresql://postgres:password@localhost:5432/comazon?schema=public"
PORT=3000
User 모델 만들기
// @id, @unique: 유니크한 값
// @default(uuid()): uuid - 36자로 이뤄진 형식
// ? : 값을 비워놔도 된다는 의미... NULL로 표시
model User {
id String @id
email String @unique
firstName String
lastName String
address String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([firstname, lastname]) // 조합이 유니크 해야하는 경우 @@unique 사용
}
마이그레이션: 모델 코드를 데이터베이스에 반영하는 것
npx prisma migrate dev
migration.sql
-- CreateTable
CREATE TABLE "User" (
"id" TEXT NOT NULL,
"email" TEXT NOT NULL,
"firstName" TEXT NOT NULL,
"lastName" TEXT NOT NULL,
"address" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
DB 접속 및 확인
npx prisma studio
테이블에 데이터가 있을 때 마이그레이션 하기
- model User 필드에 age Int 추가시 기존 데이터들은 값이 없어서 오류가 뜸
- 그래서 처음 추가할 땐 옵셔널 필드로 넣은 다음에 기존 데이터 들을 채워준 후에 필수 필드로 지정해주면 됨
- 삭제시엔 경고문만 뜨고 별로 문제가 되지 않음
Prisma Client와 DB CRUD
- Prisma 사용하기
// app.js
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
// 유저 목록 조회
const users = await prisma.user.findMany();
// id에 해당하는 유저 조회
const user = await prisma.user.findUnique({
where: { id },
});
// 리퀘스트 바디 내용으로 유저 생성
const user = await prisma.user.create({
data: req.body,
});
// 리퀘스트 바디 내용으로 id에 해당하는 유저 수정
const user = await prisma.user.update({
where: { id },
data: req.body,
});
// id에 해당하는 유저 삭제
await prisma.user.delete({
where: { id },
});
데이터베이스 시딩
import { USERS } from './mock.js';
const prisma = new PrismaClient();
async function main() {
// 기존 데이터 삭제
await prisma.user.deleteMany();
// 목 데이터 삽입
await prisma.user.createMany({
data: USERS,
skipDuplicates: true, // unique한 데이터들이 중복되면 skip
});
}
// pacage.json에 다음 코드 추가
"prisma": {
"seed": "node prisma/seed.js"
}
// 후에 npx prisma db seed를 입력하면 seed 데이터가 잘 들어간 것을 알 수 있음
쿼리 파라미터 처리하기
// app.js - app.get()을 다임과 같이 수정
app.get('/users', async (req, res) => {
// 유저 목록 조회
const { offset = 0, limit = 10, order = 'newest' } = req.query;
let orderBy;
switch (order) {
case 'oldest':
orderBy = { createdAt: 'asc' };
break;
case 'newest':
default:
orderBy = { createdAt: 'desc' };
}
const users = await prisma.user.findMany({
orderBy,
skip: parseInt(offset),
take: parseInt(limit),
});
res.send(users);
});
유효성 검사
// structs.js
import * as s from 'superstruct';
import isEmail from 'is-email';
export const CreateUser = s.object({
email: s.define('Email', isEmail),
firstName: s.size(s.string(), 1, 30),
lastName: s.size(s.string(), 1, 30),
address: s.string(),
});
export const PatchUser = s.partial(CreateUser);
// app.js에서 코드 삽입
import { assert } from 'superstruct';
import { CreateUser, PatchUser } from './structs.js';
assert(req.body, CreateUser); // post
assert(req.body, PatchUser); // patch
오류 처리하기
function asyncHandler(handler) {
return async function (req, res) {
try {
await handler(req, res);
} catch (e) {
// 유효성 검사 오류
if (e.name === 'StructError' ||
e instanceof Prisma.PrismaClientValidationError
) {
res.status(400).send({ message: e.message });
}
// 요청한 리소스를 찾을 수 없을 때
else if (
e instanceof Prisma.PrismaClientKnownRequestError &&
e.code === 'P2025'
) {
res.sendStatus(404);
} else {
res.status(500).send({ message: e.message });
}
}
};
}
728x90
반응형