ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 2019-08-19 개발일지
    개발일지 2019. 8. 19. 13:14

    오늘은 Sequelize를 사용해서 SQL 함수를 사용해야하는 상황이 발생했다.

     

    PostgreSQL의 ROW_NUMBER() OVER() 함수를 이용하여 조회한 대상에 순차번호를 매겨서 프론트 엔드에 데이터를 넘겨야했다.

    이는 시퀄라이즈의 options를 이용해서 처리할 수 있었다.

     

    코드를 보자.

    const table = await model.findAll({
        attributes: [
            [ sequelize.literal('ROW_NUMBER() OVER(ORDER BY id ASC)'), 'num' ], 
            [ 'id', 'id' ],
            [ 'content', 'content' ]
        ], 
        where: [ something: some ]
    });

     

    attributes 속성엔 조회 대상 필드에 대한 조작을 할 수 있게 해주는 속성이다.

    [ '속성 정의', '별칭' ] 형식으로, 무언가 조작을 한 후에 그에 대한 별칭을 줘서 필드를 조회 결과에 포함해준다.

    sequelize의 literal()함수는 문자 그대로를 쿼리에 반영해주는 함수다.

     

    즉 입력한 쿼리를 그대로 쿼리에 반영하여 num이라는 가상 필드로 결과에 포함시켜준다.

     

    공식 문서를 참고했고, 어렵진 않았는데 sequelize의 fn()함수로 할 수 있는 줄 알고 시도 했다가 안되서 literal()을 찾아냈다.

    무엇이 안되었냐면 fn()함수는 인자로 SQL 함수명, 인자배열(함수를 적용할 대상 컬럼)을 받는데, ROW_NUMBER()같은 경우에 함수 안에 인자를 넣지 않기 때문에 fn()함수에 fn('ROW_NUMBER()')만 작성할 경우 대상 컬럼을 넣지 않았다며 에러를 내뱉었다.

     

    참고: 

    https://sequelize.org/master/manual/querying.html#attributes

     

     

    그리고 시퀄라이즈에서 트랜잭션을 처리하는 방법을 알았다.

     

    공식문서 예제는 Promise기반으로 체이닝으로 처리하는 방법으로 보여줬는데 현재 async await를 이용해서 코딩하고 있어서 문법을 맞게끔 바꿔봤다.

     

    let transaction = null;
    
    try {
        transaction = await Model().sequelize.transaction();
        
        let table = await Model().findByPk(id);
        table = await table.update({ deleteFlag: true }, { transaction });
        
        // throw new Error(); // 트랜잭션 테스트
        await transaction.commit();
        
        return res.json({ message: 'test 성공' });
    } catch (error) {
        await transaction.rollback();
    }

     

    Model 객체의 sequelize 속성의 transaction() 함수를 할당한다.

    이 때 await 구문을 사용하니 try/catch로 에러 핸들링을 수행한다.

     

    만약 코드 처리 도중 commit()을 수행하기 전 에러가 발생하여 catch로 위치가 변경될 경우 rollback()로 실행을 롤백해준다.

    '개발일지' 카테고리의 다른 글

    2019-08-21 개발일지  (0) 2019.08.21
    2019-08-20 개발일지  (0) 2019.08.20
    2019-08-16 개발일지  (0) 2019.08.17
    휴가기간 (2019-08-12 ~ 2019-08-15)  (0) 2019.08.12
    2019-08-09 개발일지  (0) 2019.08.10
Designed by Tistory.