Final 에서는 Sequelize 를 사용해보기로 했습니다. MySQL 쿼리문을 직접 작성하던 것과 비교해 아주 간단하게 코드르 작성할 수 있었죠.
근데 findAll
로 DB 에서 데이터를 가져오려고 하니 문제가 발생했습니다. 위의 이미지에 보이는 것처럼 에러 메시지를 띄우며 서버가 crashed 되버리더라구요.
Sequelize 의 findAll
을 이용해 쿼리를 던지게 되면 Sequelize 에서 알아서 SQL 쿼리문을 만들게 되는데, 자꾸 userId 라는 존재하지도 않는 컬럼이 추가되면서 생기는 문제였습니다. 없는 컬럼의 내용을 가져오려고 하니 쿼리문이 오류를 뱉을 수 밖에 없었죠.
DB 를 가장 처음 생성할 때 userId 라는 컬럼을 만들었다가 다른 이름으로 수정한 적이 있어서 그 때문인 줄로만 알았는데, 정작 문제해결의 실마리는 엉뚱한 곳에 있었습니다.
에러가 같다고 해서 문제까지 완전히 같을 수는 없겠죠. 혹시라도 비슷한 에러 메시지로 고생하시는 분들을 위해 문제가 왜 발생했으며, 어떻게 해결했는지를 적어보겠습니다.
user
라는 테이블과 article
이라는 2 개의 테이블이 있고, 두 테이블은 일대다의 관계입니다. user.hasMany(article)
, 그리고 article.belongsTo(user)
를 활용해 Sequelize 에서 두 테이블의 관계를 형성해주었죠.
user
테이블에는 id
라는 primary key 가 있고, article
테이블에 author_id
라는 컬럼을 만들어 이를 foreign key 로 지정했습니다. 한 명의 유저가 여러 개의 게시글을 작성할 수 있기 때문인데요. 코드로 표현하면 다음과 같습니다.
user.hasMany(article, {
foreignKey: "author_id"
});
article.belongsTo(user);
위의 코드는 다음의 Sequelize 공식 문서를 참고한 내용입니다. One to One case 에서 안내하는 것과 같은 방식으로 사용이 가능하다고 되어있어서, 둘 중 하나에만 적용해줘도 될 거라고 판단했었습니다.
문제를 해결하는데 가장 큰 도움이 되었던 것은 다음의 stackoverflow 글의 답변이었습니다.
When creating a one-to-many association between models with a custom foreign key, apparently you must specify the foreign key configuration in both the belongsTo and hasMany associations (not just one of them)
custom foreign key 를 사용해 모델 간에 일대다의 관계를 형성하려면, foreign key 설정을 belongsTo
와 hasMany
둘 다에 적용해주어야 한다는 것입니다.
user.hasMany(article, {
foreignKey: "author_id"
});
article.belongsTo(user, {
foreignKey: "author_id"
});
다음과 같이 코드를 바꿔주었더니, 문제가 바로 해결되었습니다.
또 다시 찾아온 "It works..... why??" 의 시간입니다. 공식 문서에서 안내하는 것과 실제로 문제가 해결된 내용이 조금 다르다보니 조금 더 깊이 파서 문제가 발생한 원인을 알고 싶었습니다.
앞서서 85% 정도 해결되었다는 소제목을 달았는데요. 아직도 왜 둘 다 관계를 형성해주어야 하는지 정확한 이유를 알지는 못했습니다. 특히나 공식문서에서는 더더욱 그 내용을 발견할 수 없었죠.
그 대신 알아낸 것들이 있다면 다음과 같습니다.
- Sequelize 는 (관계 설정에 있어서) foreign key 를 지정해주지 않으면 알아서 컬럼을 생성한다. 이 때 컬럼의 이름은
테이블 이름 + Id
의 형식이 된다. ex) userId (user 테이블 + Id)다음의 공식문서 에서 options.foreignKey 부분의 Description 을 참고하세요.
- custom foreign key 를 설정해 일대다 관계를 형성해주려면 hasToMany 와 belongsTo 둘 다에 설정하자.
다음의 블로그 자료에서 1:다 관계 (hasMany) 부분과 댓글을 확인해보세요.
- foreign key 가 어디에 들어가야 하는지 헷갈릴 때는 다음의 공식문서를 참고하도록 하자.
공식문서만으로는 왜 둘 다 설정해주어야 하는지 정확히 알 수 없었습니다만, 여러 다른 자료들을 통해 그렇구나 하고 이해하게 되는 것 같습니다. 공식문서가 이런 부분들을 조금 더 보충해준다면 좋을 것 같다는 생각이 드네요.
혹시라도 비슷한 오류로 고생하신다면 이번 블로깅이 도움이 되었으면 합니다.