저장을 습관화
에러 기록 - SequelizeForeignKeyConstraintError 본문
- 증상
...(중략)...
const { postId } = req.params;
const { userId } = res.locals.user
...(중략)...
await this.likeService.addLike(postId, userId);
사용자 로그인한 후 Likes 테이블에 좋아요에 관한 데이터를 저장하려는 중 발생한 에러
sequelizeForeignKeyConstraintError 외래키 제약 조건 에러
에러 로그
외래키 제약 조건 때문에 전달인자로 받아온 userId를 Likes테이블의 UserId에 넣지 못한다고 나옴
Executing (default): INSERT INTO `Likes` (`likeId`,`UserId`,`PostId`,`createdAt`,`updatedAt`) VALUES (DEFAULT,?,?,?,?);
Error
at Query.run (C:\(생략)LV.5\node_modules\sequelize\lib\dialects\mysql\query.js:52:25)
at C:\(생략)LV.5\node_modules\sequelize\lib\sequelize.js:315:28
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async MySQLQueryInterface.insert (C:\(생략)LV.5\node_modules\sequelize\lib\dialects\abstract\query-interface.js:308:21)
at async Likes.save (C:\(생략)LV.5\node_modules\sequelize\lib\model.js:2490:35)
at async Likes.create (C:\(생략)LV.5\node_modules\sequelize\lib\model.js:1362:12)
at async LikeRepository.addLikePost (C:\(생략)LV.5\repositories\04_like_repository.js:32:30)
at async LikeService.addLike (C:\(생략)LV.5\services\04_like_service.js:44:5)
at async likeComment (C:\(생략)LV.5\controllers\04_like_controller.js:36:9) {
name: 'SequelizeForeignKeyConstraintError',
parent: Error: Cannot add or update a child row: a foreign key constraint fails (`lv5`.`Likes`, CONSTRAINT `Likes_ibfk_1` FOREIGN KEY (`UserId`) REFERENCES `Users` (`userId`) ON DELETE CASCADE)
at Packet.asError (C:\(생략)LV.5\node_modules\mysql2\lib\packets\packet.js:728:17)
at Execute.execute (C:\(생략)LV.5\node_modules\mysql2\lib\commands\command.js:29:26)
at Connection.handlePacket (C:\(생략)LV.5\node_modules\mysql2\lib\connection.js:497:34)
at PacketParser.onPacket (C:\(생략)LV.5\node_modules\mysql2\lib\connection.js:97:12)
at PacketParser.executeStart (C:\(생략)LV.5\node_modules\mysql2\lib\packet_parser.js:75:16)
at Socket.<anonymous> (C:\(생략)LV.5\node_modules\mysql2\lib\connection.js:104:25)
at Socket.emit (node:events:513:28)
at addChunk (node:internal/streams/readable:324:12)
at readableAddChunk (node:internal/streams/readable:297:9)
at Readable.push (node:internal/streams/readable:234:10) {
code: 'ER_NO_REFERENCED_ROW_2',
errno: 1452,
sqlState: '23000',
sqlMessage: 'Cannot add or update a child row: a foreign key constraint fails (`lv5`.`Likes`, CONSTRAINT `Likes_ibfk_1` FOREIGN KEY (`UserId`) REFERENCES `Users` (`userId`) ON DELETE CASCADE)',
sql: 'INSERT INTO `Likes` (`likeId`,`UserId`,`PostId`,`createdAt`,`updatedAt`) VALUES (DEFAULT,?,?,?,?);',
parameters: [ '4', 18, '2023-07-14 04:14:24', '2023-07-14 04:14:24' ]
},
original: Error: Cannot add or update a child row: a foreign key constraint fails (`lv5`.`Likes`, CONSTRAINT `Likes_ibfk_1` FOREIGN KEY (`UserId`) REFERENCES `Users` (`userId`) ON DELETE CASCADE)
at Packet.asError (C:\(생략)LV.5\node_modules\mysql2\lib\packets\packet.js:728:17)
at Execute.execute (C:\(생략)LV.5\node_modules\mysql2\lib\commands\command.js:29:26)
at Connection.handlePacket (C:\(생략)LV.5\node_modules\mysql2\lib\connection.js:497:34)
at PacketParser.onPacket (C:\(생략)LV.5\node_modules\mysql2\lib\connection.js:97:12)
at PacketParser.executeStart (C:\(생략)LV.5\node_modules\mysql2\lib\packet_parser.js:75:16)
at Socket.<anonymous> (C:\(생략)LV.5\node_modules\mysql2\lib\connection.js:104:25)
at Socket.emit (node:events:513:28)
at addChunk (node:internal/streams/readable:324:12)
at readableAddChunk (node:internal/streams/readable:297:9)
at Readable.push (node:internal/streams/readable:234:10) {
code: 'ER_NO_REFERENCED_ROW_2',
errno: 1452,
sqlState: '23000',
sqlMessage: 'Cannot add or update a child row: a foreign key constraint fails (`lv5`.`Likes`, CONSTRAINT `Likes_ibfk_1` FOREIGN KEY (`UserId`) REFERENCES `Users` (`userId`) ON DELETE CASCADE)',
sql: 'INSERT INTO `Likes` (`likeId`,`UserId`,`PostId`,`createdAt`,`updatedAt`) VALUES (DEFAULT,?,?,?,?);',
parameters: [ '4', 18, '2023-07-14 04:14:24', '2023-07-14 04:14:24' ]
},
sql: 'INSERT INTO `Likes` (`likeId`,`UserId`,`PostId`,`createdAt`,`updatedAt`) VALUES (DEFAULT,?,?,?,?);',
parameters: [ '4', 18, '2023-07-14 04:14:24', '2023-07-14 04:14:24' ],
table: 'Users',
fields: [ 'UserId' ],
value: '4',
index: 'Likes_ibfk_1',
reltype: 'child'
}
- 원인과 해결
외래키 제약 조건 에러
Likes 테이블의 컬럼 UserId는
Users 테이블의 기본키 userId를 외래키로 받아오도록 설정되어 있음
- /models/users.js
...(생략)...
static associate(models) {
...(생략)...
this.hasMany(models.Likes, {
sourceKey: "userId",
foreignKey: "UserId",
});
}
...(생략)...
- /models/likes.js
...(생략)...
static associate(models) {
// define association here
this.belongsTo(models.Users, {
targetKey: "userId",
foreignKey: "UserId",
});
...(생략)...
적어도 테이블 간 관계 문제는 없었음..
원인을 찾기 위해 로직의 흐름에 따라가며 각 부분에 로그를 찍은뒤 실행했고
// /controllers/04_like_controller.js
...
// 좋아요, 좋아요 취소 로직
const didILike = await this.likeService.findLikedPost(userId, postId);
console.log("기존 좋아요 확인 부분의 userId", userId);
if (!didILike) {
// 없다면 좋아요 등록
console.log("아직 좋아요 하지 않았습니다. - 04_like_controller.js");
console.log("좋아요 등록 부분의 userId", userId);
await this.likeService.addLike(postId, userId);
return res.status(200).json({ LIKE: "해당 게시글에 좋아요 했습니다." });
}
...
// /services/04_like_service.js
...
// 게시글 좋아요
addLike = async (userId, postId) => {
console.log("게시글 좋아요 부분의 userId", userId);
await this.likeRepository.addLikePost(userId, postId);
return;
};
...
// /repositories/04_like_repository.js
...
// 게시글 좋아요
addLikePost = async (userId, postId) => {
console.log("여기까진 들어옴", userId);
try {
const createLikeData = await Likes.create({
UserId: userId,
PostId: postId,
});
return createLikeData;
} catch (error) {
console.log(error);
}
};
...
출력된 로그는 아래와 같았음
기존 좋아요 확인 부분의 userId 18
아직 좋아요 하지 않았습니다. - 04_like_controller.js
좋아요 등록 부분의 userId 18
게시글 좋아요 부분의 userId 4
여기까진 들어옴 4
이를 통해 /controllers/04_like_controller.js에서 /services/04_like_service.js로 인자를 넘기는 동안
userId와 postId가 서로 뒤바뀌고 있다는 것을 확인함
해당 부분을 살펴 보니
/controllers/04_like_controller.js에서는 전달인자를 postId, userId 순으로 보냈으나
await this.likeService.addLike(postId, userId);
/services/04_like_service.js 에서는 매개변수를 userId, postId 순으로 받아 사용하였음
addLike = async (userId, postId) =>
그래서 원래 userId: 18, postId: 4 인 것이
userId: 4, postId: 18로 처리 되었고
코드는 Likes 테이블에 UserId에 4, PostId에 18을 저장하려 했으나
Users 테이블에 userId 4가 없었기에 외래키 제약 조건 에러가 발생한 것
해당 부분의 순서를 수정, 실행한 뒤 로그 확인
존 좋아요 확인 부분의 userId 18
아직 좋아요 하지 않았습니다. - 04_like_controller.js
좋아요 등록 부분의 userId 18
게시글 좋아요 부분의 userId 18
여기까진 들어옴 18
// 정상
Likes 테이블 조회
정상 등록 확인
바쁘다고 코드 막 구겨넣지 말자
'공부 > node.js' 카테고리의 다른 글
Nest.js 입문 기록 (0) | 2023.08.04 |
---|---|
S3 버킷 사용하여 이미지 저장하기 + access key 받아오기(IAM) (0) | 2023.07.26 |
MySQL sequelize 연습 기록 3 (0) | 2023.07.13 |
에러 기록 - TypeError: Router.use() requires a middleware function but got a Object (0) | 2023.07.09 |
MySQL sequelize 연습 기록 2 (0) | 2023.07.08 |