| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | |||||
| 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 24 | 25 | 26 | 27 | 28 | 29 | 30 |
| 31 |
- 카카오뷰 초보
- 엑셀 기초 함수
- 카뷰 수익 인증
- HTML
- 카카오뷰N잡
- 카카오뷰 수익
- 성공비법
- 도서 원씽
- 위드굿즈 굿즈샵
- 웹기초
- ppt 도형 색
- 원씽
- 카카오뷰 성장
- 30일 글쓰기
- 실시간 통신
- 책 원씽
- Git 팀 작업
- 자기관리
- 위드굿즈
- git 협업하기
- CSS
- 카카오뷰 부업
- 카카오뷰 온라인 수익화
- express.js 환경 셋팅
- 카카오뷰 탭이동
- ppt 다이어그램
- 이석증
- Axios 라이브러리
- 성공에 대한 거짓말
- 엑셀 프린트하기
- Today
- Total
김데이의 개발공부
[ TIL ] Day 21 - 관계형 데이터베이스 / Postgres 사용하기 2 본문
[ TIL ] Day 21 - 관계형 데이터베이스 / Postgres 사용하기 2
theday365 2025. 10. 24. 18:46🗓️ 수업 일자 : 2025.10.24
✨ 오늘의 수업 평가 : [ GOOD ] 오늘도 한 걸음 성장! 🌱✨🌙
최종 Git Repo : https://github.com/KimDay366/codeit-nodejs-6th-comazon
GitHub - KimDay366/codeit-nodejs-6th-comazon: codeit-nodejs-6th, Comazon project Repo
codeit-nodejs-6th, Comazon project Repo. Contribute to KimDay366/codeit-nodejs-6th-comazon development by creating an account on GitHub.
github.com
코드를 보면 주석 범벅이라 내용은 진짜 정신 없지만,
그래도 강사님 코드 안보고 작성 해 보고, 에러 날 때마다 혼자 해결했다는게 참 뿌듯한 날이다 😉👍
📝 오늘 배운 내용
- 여러 OMR 기능 / 문법 익히기 2
- 모델 간 관계 정립 @relation
- 지금까지 배운 ORM / Prisma 개념 한 줄 정리
1. 여러 ORM 기능/문법 익히기 2
Prisma에서 Transaction
- 서버에 작업을 요청하는 도중 서버에 문제가 생겨 일부 쿼리만 실행되는 경우에 대한 문제 방지
예시 ) [ 주문 진행 = 재고 확인 → 재고 수정 → 주문 생성 ] 과정에서 서버 다운이 되면서 재고 수정만 되고 주문이 생성되지 않으면 재고에 대한 문제가 생김. - 여러 쿼리(실제 데이터를 가져오는 메소드)를 $transaction 안에 묶어서 모든 작업이 성공하지 않으면 롤백하여 모든 작업이 실패 하도록 설정
- 사용 예제
[ Transaction 없이 사용 한 경우 ]
const queries = productIds.map((id) => { ... }); // 재고를 수정하는 코드
const orderCreat = await prisma.order.create({ ... }); // 오더를 등록하는 코드
queries가 실행 된 뒤, 모종의 이유로 서버 연결이 중단되면 orderCreat가 실행되지 않음
[ Transaction으로 처리 한 경우 ]
const queries = productIds.map((id) => { ... }); // 재고를 수정하는 코드
const [ orderCreat ] = await prisma.$transaction([
prisma.order.create({
... // 오더를 등록하는 코드
}),
... queries // 수정된 재고 값
]);
[ orderCreat ] 안에 오더 등록 / 재고 모두 담겨있음
해당 구문을 진행하는 도중 서버가 중단되면, 모든 구문이 정지되어 일관성을 유지
비동기 라우트 핸들러용 에러 래퍼 함수 ( Async Route Handler Wrapper)
혹은 비동기 에러 처리용 고차함수 (Higher-Order Function for Async Error Handling)
또는 에러 래퍼 함수, 비동기 에러 래퍼 함수 등등.. with asyncHandler(){}
- 에러가 발생하는 경우 서버가 다운되지 않고 유지하면서 에러를 내보낼 수 있게 셋팅
- 함수를 인자로 받고, 새로운 async 함수를 다시 돌려줌
- 모든 라우터 핸들러에 설정할 수 있는 고차함수로 구성
- catch문 안에 if문으로 에러를 하나하나 찾아내 확인 할 수 있음
function asyncHandler(handler) {
return async function (req, res) {
try {
// 실행 하려는 HTTP 작업이 실행되는 공간
await handler(req, res);
} catch (e) {
console.error(e);
// if 구문으로 에러 값을 적어서 여러 에러를 처리 가능!
if (e instanceof Prisma.PrismaClientKnownRequestError && e.code === 'P2025') {
res.sendStatus(404);
} else if (e.name === 'StructError') {
res.status(400).send({ message: e.message });
} else {
res.status(500).send({ message: e.mossage });
}
}
};
}
...
app.post('/user', asyncHandler( asycn (req,res) => {
... asyncHandler에 감싸진 상태로 요청 코드 작성 ...
}),
);
+ Prisma Error 관련 링크 : https://www.prisma.io/docs/orm/reference/error-reference
Errors | Prisma Documentation
Prisma Client, Migrate, Introspection error message reference
www.prisma.io
배포하기
- PostgreSQL Database 생성
- render.com 홈페이지에서 New > Progres 클릭하여 신규 DB 생성
- Web Service 셋팅 ( build commend 참고 사항 )
- npm install --production : 배포용 패키지 설치
- npx prisma migrate deploy : 배포 할 때 가장 최신 버전의 마이그레이션으로 DB에 정보를 생성
(npx prisma migrate dev : 개발 작업 시 data model이 바뀔때마다 실시간으로 DB를 생성) - npx prisma generate : prisma client 설치
⇒ Build Command에 한번에 입력
: npm install --production && npx prisma migrate deploy && npx prisma generate
2. 모델 간 관계 정립 @relation (어제 배운거 포함)
0) 관계 정립 기본 문법
[ data model 영역]
model User {
order Order[]
}
model Order {
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
userId String @unique
}
위 코드 내용은 문법에 맞지 않습니다. 다양한 내용을 보여주기 위해 샘플로 작성하였습니다 :)
- 참조를 사용 할 모델(=model Order)에서 @relation 하기
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
사용 할 값 이름 | 참조 할 model이름 | @relation( fields, references, onDelete(optinal) )
- fields: [ 현재 모델에서 사용할 필드 이름 ]
- references: [ 참조 할 필드 이름 ]
- onDelete: 참조 데이터가 삭제될 때 설정 - 참조를 사용 할 모델(=model Order)에서 불러온 값 정의하기
userId String @unique
@relation에서 작성한 fields 값 | 해당 값의 속성 | 1:1 매칭이면 @unique 사용 - 참조를 보낸 모델(=model User)에서 연결되는 필드값 정리하기
orders Order[] (속성 x)
참조 보낼 필드값 이름 | 해당 모델명을 작성하며 어떻게 받을지도 결정
(단일 - 로우 받음, [ ] - 해당 모델들의 로우를 배열로 받음)
- model Order에서 @relation을 통해 생성된 두 Data 필드의 차이
1) user : 데이터가 오고가는 통로, 별도의 값이 존재하지 않음
2) userId : 통로를 통해 만들어진 실제로 사용되는 값
+ orders : 데이터가 오고 가는 통로, 속성값을 보면 한 개가 아닌 여러 개의 로우 데이터를 받을 수 있음
1) ||--|| : 1:1 관계, One and only one
[ data model 영역]
model User {
id String @id @default(uuid())
...
userPreference UserPreference?
}
model UserPreference {
...
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
userId String @unique
...
}
[ 작성 조건 ]
- model User의 ID정보를 model Userpreference에서 사용
- model Userpreference는 model User이 생길 때 함께 생기는 "마이페이지" 데이터 ⇒ 두 모델이 1:1 단일 매칭
[ model User의 입장 ]
model User에서 참조하는 "UserPreference"는 "UserPreference"에 속해 있는 값 중 하나가 아니라,
"UserPreference의 로우 1줄" 전체임
[ model UserPreference 의 입장 ]
참조하여 가지고 온 UserId의 경우 1 : 1 관계로 참조하기 때문에 @unique를 써야 함
(만약에 다른 경우로 쓴다면 @unique를 쓰면 안됨!)
2) ||--o{ : 1:n 관계, Zero or many
[ data model 영역]
model User {
id String @id @default(uuid())
...
posts Post[]
}
model Post {
...
user User @relation(fields: [userId], references: [id], onDelete: SetNull)
userId String?
...
}
[ 작성 조건 ]
- model User의 ID정보를 model Post에서 사용
- 하나의 User는 여러 Post를 작성할 수 있음 ⇒ model User와 model Post이 1: 다수 매칭인 경우
[ model User의 입장 ]
model User에서 참조하는 Post는 하나가 아니므로 배열로 선언
[ model Post의 입장 ]
참조하여 가지고 온 userId의 경우 Post 관점에서는 1 : 1 관계로 보이지만,
User 입장에서 볼땐 Post가 여러개이므로, UserID의 속성에 @unique를 쓰면 안됨
3) }o--o{ : n:m 관계, Many to many
[ data model 영역]
model User {
id String @id @default(uuid())
...
joingroups Group[]
}
model Group {
...
members User[]
...
}
[ 작성 조건 ]
- model User 는 하나의 사람이고, model Group은 하나의 소규모 그룹임
- 하나의 User는 여러 Group에 가입할 수 있고, Group 역시 여러 사람을 데리고 있을 수 있음
⇒ model User와 model Group이 다수 : 다수 매칭인 경우
[ model User의 입장 ]
model User에서 참조하는 Group는 하나가 아니므로 배열로 선언
[ model Group의 입장 ]
model Group에서 참조하는 User는 하나가 아니므로 배열로 선언
[ 특이사항 ]
작업이 끝난 뒤 마이그레이션을 진행하면 양쪽 테이블을 이어주는 임의의 중간 테이블이 자동으로 생김

3. 지금까지 배운 ORM / Prisma 개념 한 줄 정리
- 작업 관련
- seeding(시딩) : 작업에 필요한 초기 데이터를 서버에 넣는 과정
- @relation : 각 데이터 모델간의 관계를 정립할 때 사용하는 명령어
- 스키마 : 데이터베이스의 model / 값 이름 및 속성 / 관계 / 관련 카테고리들을 정의하는 것
- 마이그레이션 : 실제 데이터 베이스에 작성한 Data Model을 저장 하는 것
- 에러 처리
- asyncHandler( ) : 에러가 생겨도 서버를 다운 시키지 않는 것
- assert( ) & Superstruct : 입력할 데이터 자체에 대한 검증
- $transaction([ ]) : 서버가 중간에 중단되면, 작업한 내용을 모두 롤백 시켜서 데이터가 꼬이는 것을 방지
- 배포 진행
- 환경 설정 : 배포 진행 할 때, 공개되면 안되는 정보 혹은 배포에 필요한 정보에 대해 설정하는 것
- Build Command : 배포 작업에 사용 될 명령어 모음, 배포용 패키지 / 마이그레이션 작업 / 클라이언트 선언 등
Start Command : 배포 후 실행되는 첫 명령어, html로 치면 index.html을 지정 해 주는 것
- 기타 개념
- Cardinality : 데이터 모델간의 관계에 대한 이론
- UUID : 완벽하게 고유 문자는 아니지만, 중복 가능성이 거의 없는 ID
- enum : 데이터에 사용하는 값이 특정 카테고리일 경우, enum을 활용하여 카테고리 생성 & 정의
📃 내일은 뭘 배울까 🤔
- 미들 웨어와 파일 관리
- 밀린 LMS 강의 듣기(제발 좀 밀리지 마🙏)
'코드잇 Node.js(BE) 부트 캠프 > TIL (Today I Learn) 📑' 카테고리의 다른 글
| [ TIL ] Day 23 - 실습 개발 환경 셋팅하기 (Git, Express, 전체 구조) (0) | 2025.10.28 |
|---|---|
| [ TIL ] Day 22 - Express 미들웨어 / 라우트 / Multer(파일 업로드) (0) | 2025.10.27 |
| [ TIL ] Day 20 - 관계형 데이터베이스 / Postgres 사용하기 (0) | 2025.10.23 |
| [ TIL ] Day 19 - DB 기초이론 & ER모델 / 관계형 데이터베이스(Postgres)와 서버 (0) | 2025.10.22 |
| [ TIL ] Day 18 - 💡드디어 데이터 베이스와 ORM / MongoDB & Mongoose / 서비스 배포하기! ✨🖥️🌐 (0) | 2025.10.21 |