JavaScript ORM 라이브러리인 Sequelize를 사용하면서 아래와 같은 에러가 발생하는 경우가 있습니다.
node:internal/process/promises:246 triggerUncaughtException(err, true /* fromPromise */); ^ AssertionError [ERR_ASSERTION]: Missing where attribute in the options parameter at Function._optionsMustContainWhere (C:\Source\MyProject\node_modules\sequelize\lib\model.js:2070:5) at Function.update (C:\Source\MyProject\node_modules\sequelize\lib\model.js:1836:10) at model.Users.resetAllPoints(file:///C:/Source/MyProject/server/models/Users.js:61:82) at Job.job (file:///C:/Source/MyProject/server/middlewares/users.js:59:34) at processTicksAndRejections (node:internal/process/task_queues:96:5) Emitted 'error' event on Job instance at: at C:\Source\MyProject\node_modules\node-schedule\lib\Invocation.js:277:17 at processTicksAndRejections (node:internal/process/task_queues:96:5) { generatedMessage: false, code: 'ERR_ASSERTION', actual: undefined, expected: true, operator: '==' }
위 에러 로그에서 확인할 수 있는 문제는 AssertionError [ERR_ASSERTION]: Missing where attribute in the options parameter인데, 이는 요청 트랜잭션에서 누락된 쿼리문이 있어서 발생하는 문제입니다.
해결 방법
이 문제는 주로 데이터베이스 UPDATE문을 사용할 때 모든 행에 적용하기 위해 특별한 WHERE 조건 없이 메소드를 호출했을 경우 발생합니다. 예를 들면 아래와 같습니다.
Users.prototype.resetAllPoints = () => Users.update({ point: 0 });
resetAllPoints
가 호출되면 모든 사용자의 point
가 UPDATE문으로 인해 0으로 초기화됩니다. 하지만 이렇게 하면 에러가 발생합니다. 아무래도 sequelize 라이브러리에서 WHERE문 없는 UPDATE문은 위험한 쿼리라고 판단해서 의도적으로 에러를 리턴하도록 설계했을 수 있습니다.
모든 행에 적용하면서도 위와 같은 문제를 해결하려면 모든 행을 가리키는 임의의 WHERE문을 추가하는 방법으로 해결할 수 있습니다. 위 예시에서는 id
열의 모든 값(0 이상의 값)을 선택하도록 지정해주었습니다. 데이터베이스 환경에 따라 컬럼명이나 값들이 다를 수 있으므로 범위를 확인한 후 작성해야 합니다.
Users.prototype.resetAllPoints = () => Users.update({ point: 0 }, { where: { id: { [Op.gte]: 0 } } });
이렇게하면 더 이상 에러가 발생하지 않을 것입니다.