[Sequelize] UPDATE id = id + 1 (increment, decrement)

스윗포테이토·2023년 1월 27일
0

sequalize를 이용해서 값을 증가 혹은 감소시키는 방법에 대해 정리해보려고 한다. 하려고 하는 동작을 SQL 문으로 작성해보자면 아래와 같다.

UPDATE 테이블 명
	SET COL = COL + 1
    WHERE 조건

특정 컬럼의 값을 1 증가시키는 것이다.

update

값을 변경할 때 사용하는 update 문을 사용할 수 있다.
update의 기본적인 활용은 다음과 같다.

// Change everyone without a last name to "Doe"
await User.update({ lastName: "Doe" }, {
  where: {
    lastName: null
  }
});

그러나, 특정 데이터의 값을 1 늘리기 위해서는 해당 값의 기존 정보를 알고 있어야 한다. 따라서 이 경우에는

const user = await models.User.findByPk(id);
await user.update({ age: user.age + 1});

이렇게 update문을 사용할 수 있다.

increment / decrement

혹은 sequalize가 제공하는 increment, decrement을 사용할 수도 있다. 말 그대로 값을 늘리거나 줄이는 함수이고, 사용법은 다음과 같다.

만약 이미 검색한 인스턴스가 있는 경우,

await user.increment("age", {by: 1});

위와 같이 쓰면 기존 값에 1을 더하게 된다. 만약 더하는 값이 1이라면, by 값은 생략해도 좋다.

혹은 조건을 걸어서 모델에 대해 사용할 수도 있다.

await models.User.increment("age", { where: {
	id: {
    	[Op.eq]: "id",
    },
}});

decrement도 똑같이 사용할 수 있다. increment의 by 값에 음수를 주는 것과 같은 동작을 하는듯.

update vs increment

둘의 차이는 실행 전후에 콘솔을 찍어보면 알 수 있다.

const user = await models.User.findByPk(id);
console.log(user.age); // 1

await user.update({ age: user.age + 1});
console.log(user.age); // 2

await user.increment("age");
console.log(user.age); // 2

DB에 저장된 age 값이 1이었다고 하면, 두번째 출력은 2, 세번째 출력은 3이라고 예상할 수 있다. 하지만 세번째 출력에서도 값은 2로 찍히는 것을 볼 수 있다.

DB에 반영되지 않아서가 아니라, update와 increment는 작동 방식에 차이가 있기 때문이다.

우선 update에 대한 공식 문서를 보면,

set을 호출한 후에 save를 수행한다고 되어 있다.
set의 설명을 보자.
instance를 update하기 위해 쓰이며, save 호출 전에는 결과가 저장되지 않을 것이라고 나와 있다.

즉, update를 실행할 경우, 우선 set을 수행하여 인스턴스 값을 수정한 후, save를 통해 해당 인스턴스 값을 DB에 저장하게 된다. 반면 increment의 설명을 보자.

데이터베이스단에서 수행된다고 되어있다. 즉, 인스턴스를 수정하는 과정이 생략된 것이다. 따라서 마지막 user.age의 값은 업데이트 되지 못한 채 2로 남아있는 것이다.

사실 블로그 안썼으면 대충 되는대로 넘어갔을 것 같은데, 쓰다보니 찝찝한 부분을 해결하려고 공식문서를 찾게 되었다. 그리고 공식 문서에는 모든게 있다 그냥 내가 처음에 못본 것일 뿐...


reference

Sequelize - increment

profile
나의 삽질이 미래의 누군가를 구할 수 있다면...

0개의 댓글