일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- jest
- 공룡게임
- nodejs
- 정렬
- cookie
- class
- Express
- MongoDB
- 게임
- game
- react
- Python
- AWS
- MySQL
- Queue
- mongoose
- Nest.js
- Bull
- JavaScript
- TypeScript
- 자료구조
- flask
- Dinosaur
- GIT
- OCR
- nestjs
- dfs
- Sequelize
- typeORM
- Today
- Total
포시코딩
3월21일 - [TypeORM] get softDeleted data 본문
개요
MySQL의 어떤 테이블에서 softDelete를 한 데이터만 가져와야 하는 특수한 상황이 생겼다.
첫 번째 row에 있는 혼자 deletedAt이 null이 아닌 데이터를 가져와야 하는 상황.
deletedAt이 null인 데이터들을 가져올 때 알아서 걸러주기 때문에
deletedAt의 데이터가 있는 데이터를 가져와야 하는 상황은 처음 다뤄봤는데
이런 특수한 상황에 대해 생각보다 잘못된 정보가 많아 정리하게 되었다.
시행착오 1. find()에서의 시도
처음에는 그냥 softDelete된 데이터를 빼고 가져올 때
find({ where: { deleted: null } })
위 코드를 쓸 때 처럼 반대로 쓰면 되지 않을까 하여
not null을 쓰기 전 null은 먹히나 테스트 해봤는데
async getChats(userId: number): Promise<Meetup[]> {
return await this.chatRepository.find({
where: { deletedAt: null }
})
}
이런 코드를 작성했을 때
null 대신 undefined 를 사용하라는 문구가 뜨며 에러가 발생했고
undefined를 썼을 때 데이터는 가져와 졌지만 애초에 softDelete 된 데이터는 굳이 저런걸 붙이지 않아도
제외하고 가져오기 때문에 소용 없었다.
많은 구글링 결과로 typeorm에서 제공하는 Not()이나 IsNull()을 사용하여
Not(null), Not(IsNull()) 등을 사용해봤지만 안되는건 마찬가지였다.
find()를 사용한 방법으로는 안되는거라 생각해
repository를 만들어 createQueryBuilder() 를 사용하는 방법으로 선회해보았다.
시행착오 2. createQueryBuilder()에서의 시도
repository
// ...import 생략
@Injectable()
export class ChatRepository extends Repository<Meetup> {
constructor(private dataSource: DataSource) {
super(Meetup, dataSource.createEntityManager());
}
async getChats(userId: number): Promise<Meetup[]> {
return await this.createQueryBuilder('m')
.select()
.where('deletedAt IS NOT NULL')
.orderBy('m.id', 'DESC')
.getMany();
}
}
코드 작성은 위와 같이 진행했고
내가 봤을 때 문제 없어 보였다. 에러도 없었고
하지만 결과는 빈 배열.
.where('deletedAt: deletedAt', {
deletedAt: Not(null)
})
이후 위와 같은 방법들도 써봤는데 빈 배열은 커녕 해당 api를 호출하면 에러가 발생하는 문제가 있었다.
해결 방법
그렇게 계속 방법을 찾다가
withDeleted() 라는 키워드를 발견했다.
async getChats(userId: number): Promise<Meetup[]> {
return await this.createQueryBuilder('m')
.select()
.withDeleted()
.orderBy('m.id', 'DESC')
.getMany();
}
바로 적용해보았는데
softDelete된 데이터를 포함해 deletedAt이 null인 데이터들까지 모두 가져와준다는 것을 확인했다.
한 걸음 진전된건 좋은데
'softDelete 된 것'만 가져오고 싶은 상황이라
조금 더 확인해보니
이 상태로 아까 사용했을 때 반응이 없던
where('deletedAt IS NOT NULL')을 씀으로써 해결할 수 있다는 정보를 얻었다.
그니까 withDelete()로 전체 데이터 가져옴 -> where()문으로 그 중에서 softDelete된 애만 가져옴
그렇게 완성된 코드는 다음과 같다.
async getChats(userId: number): Promise<Meetup[]> {
return await this.createQueryBuilder('m')
.select()
.withDeleted()
.where('deletedAt IS NOT NULL')
.orderBy('m.id', 'DESC')
.getMany();
}
이렇게 성공적으로 softdelete된 데이터만 가져오는 것에 성공할 수 있었다.
'TIL' 카테고리의 다른 글
3월23일 - Event Bubbling 이벤트 버블링 (0) | 2023.03.23 |
---|---|
3월22일 - e.target으로 class 추가할 때 생기는 문제 (0) | 2023.03.22 |
3월20일 - Nest.js TypeORM get random row (0) | 2023.03.20 |
3월16일 - MySQL, TypeORM, RDS timezone 문제 [해결] (0) | 2023.03.16 |
3월15일 - TypeORM과 UTC Time zone 문제.. 인줄 알았으나 RDS 타임존 문제.. 인줄 알았으나 내 코드 문제 (0) | 2023.03.15 |