'ER_BAD_FIELD_ERROR'(feat.Sequelize) (Devlog 8일차)

EenSung Kim·2021년 8월 9일
1


Unknown column 'userId' in 'field list'

Final 에서는 Sequelize 를 사용해보기로 했습니다. MySQL 쿼리문을 직접 작성하던 것과 비교해 아주 간단하게 코드르 작성할 수 있었죠.

근데 findAll 로 DB 에서 데이터를 가져오려고 하니 문제가 발생했습니다. 위의 이미지에 보이는 것처럼 에러 메시지를 띄우며 서버가 crashed 되버리더라구요.

Sequelize 의 findAll 을 이용해 쿼리를 던지게 되면 Sequelize 에서 알아서 SQL 쿼리문을 만들게 되는데, 자꾸 userId 라는 존재하지도 않는 컬럼이 추가되면서 생기는 문제였습니다. 없는 컬럼의 내용을 가져오려고 하니 쿼리문이 오류를 뱉을 수 밖에 없었죠.

DB 를 가장 처음 생성할 때 userId 라는 컬럼을 만들었다가 다른 이름으로 수정한 적이 있어서 그 때문인 줄로만 알았는데, 정작 문제해결의 실마리는 엉뚱한 곳에 있었습니다.


85% 정도의 해결

에러가 같다고 해서 문제까지 완전히 같을 수는 없겠죠. 혹시라도 비슷한 에러 메시지로 고생하시는 분들을 위해 문제가 왜 발생했으며, 어떻게 해결했는지를 적어보겠습니다.

테이블 사이의 관계

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 설정을 belongsTohasMany 둘 다에 적용해주어야 한다는 것입니다.

user.hasMany(article, {
  foreignKey: "author_id"
});
article.belongsTo(user, {
  foreignKey: "author_id"
});

다음과 같이 코드를 바꿔주었더니, 문제가 바로 해결되었습니다.

문제가 해결은 됐는데, 대체 왜?

또 다시 찾아온 "It works..... why??" 의 시간입니다. 공식 문서에서 안내하는 것과 실제로 문제가 해결된 내용이 조금 다르다보니 조금 더 깊이 파서 문제가 발생한 원인을 알고 싶었습니다.

앞서서 85% 정도 해결되었다는 소제목을 달았는데요. 아직도 왜 둘 다 관계를 형성해주어야 하는지 정확한 이유를 알지는 못했습니다. 특히나 공식문서에서는 더더욱 그 내용을 발견할 수 없었죠.

그 대신 알아낸 것들이 있다면 다음과 같습니다.

  1. Sequelize 는 (관계 설정에 있어서) foreign key 를 지정해주지 않으면 알아서 컬럼을 생성한다. 이 때 컬럼의 이름은 테이블 이름 + Id 의 형식이 된다. ex) userId (user 테이블 + Id)
다음의 공식문서 에서 options.foreignKey 부분의 Description 을 참고하세요.
  1. custom foreign key 를 설정해 일대다 관계를 형성해주려면 hasToMany 와 belongsTo 둘 다에 설정하자.
다음의 블로그 자료에서 1:다 관계 (hasMany) 부분과 댓글을 확인해보세요.
  1. foreign key 가 어디에 들어가야 하는지 헷갈릴 때는 다음의 공식문서를 참고하도록 하자.

Outro

공식문서만으로는 왜 둘 다 설정해주어야 하는지 정확히 알 수 없었습니다만, 여러 다른 자료들을 통해 그렇구나 하고 이해하게 되는 것 같습니다. 공식문서가 이런 부분들을 조금 더 보충해준다면 좋을 것 같다는 생각이 드네요.

혹시라도 비슷한 오류로 고생하신다면 이번 블로깅이 도움이 되었으면 합니다.

profile
iOS 개발자로 전직하기 위해 공부 중입니다.

0개의 댓글