개발.코딩

Foreign key constraint is incorrectly formed 에러 sequelize 에러핸들링

스마트스타일 2021. 12. 9. 03:06
반응형

팀원들과 팀프로젝트의 리팩터를 하던 중 전날 변경사항을 모두 git에 PR하고 병합된 내용을 pull해온 후 데이터베이스 관련 에러를 만났다.

스키마 변경사항을 적용 및 반영하기위해

npx sequelize-cli db:migrate:undo:all 로 일종의 초기화 세팅으로 돌아감

npx sequelize-cli db:migrate(에러발생) 변경된 모델과 마이그레이션을 기반으로 테이블 생성 하는데 여기서 에러발생하였다.

에러명: Can't create table `dbName`.`tableName` (errno: 150 "Foreign key constraint is incorrectly formed")

무슨 에러 인지 아에 감이 오지 않았다. 직접 작업한내역에서 에러가 발생해도 감잡기 쉽지 않은데, 팀원의 코드에서 발생하였다.

데이터베이스내에서 특정 테이블을 만들 수 없다고 한다. 그 이유는 외래키 제약 형태가 잘못되었다고 한다.

마이그레이션 파일을 보니 전날 새로 생겨난 파일이 있었고, 여기를 한번 뜯어보기로했다.

21년 12월07일 작업으로 바로 전날의 제일 최근 작업이다.

항상 작업해오던 마이그레이션파일의 이름과 형태는 아래 사진과 같은 형식이었다.

 테이블을 만들기위해 npx sequelize-cli db:create로 생성해왔고, 그 후 필요한 column이 생길경우 addColumn메소드를 사용하지 않고 모델파일과 마이그래이션파일을 동시에 수정하여 컬럼을 추가해왔었기에 addColumn메소드를 사용하는것은 생소했다.

 스키마에 컬럼을 추가할때 팀원이 작성한 코드 

 봐도 잘 이해가 되지 않는다. 본적이 없어서 익숙하지 않은게 맞는것 같다. (맨날 하던대로 하면 아는방식으로만 편하게 반복만 하려하는데 타른사람이 짠 코드를 보니 색다른 공부가 되는것 같다.)

영어와 같은 외국 언어를 공부할 때도 전체적인 맥락을 이해하며 공부하는 방법이 있듯이, 이 코드 또한 에러와 연관지어 코드의 맥락을 이해 해보도록 하겠다.

 

await queryInterface.addColumn("likes", "post_id", Sequelize.STRING)
//addColumn메소드는 단어 그대로 column을 add하겠다는 것으로 보인다. 인자들을 살펴 보면
//column추가가 필요한 table명으로 보인다.
//post_id은 추가될 column의 이름에 할당될 내용으로 보인다.
//Sequelize.STRING는 tables에서 해당 column이 가지게될 데이터타입을 설정한것으로 보이며 문자로 설정되었다.

//아래의 코드는 column을 추가하는 것 외에 추가 적인 설정이나 옵션이 필요할경우 사용하는 것으로 보인다.
await queryInterface.addConstraint("likes", {
//Constraint(제약)을 add하겠다는 구문으로 예상된다.
//likes는 제약을 추가할 table명인것 같다.
            fields: ["post_id"],      // 제약을 설정할 column을 선택한다.
            type: "foreign key",      // "post_id"을 foreign key키로 설정한다.(확실하지않다)
            name: "custom_fkey_name", 
            references: {             // foreign key로 설정하려면 어떤 pk를 사용할지 정해야하는곳 같다.
                table: "posts",       // posts테이블의 
                field: "id",          // id column을 pk로써 참조하겠다는 것 같다.
            },
            
            //근데 왜 오류가 발생할까?

근데 왜 오류가 발생했을까?

바로 구글링으로 찾아보니, FK와 PK를 이어줄때 같은 데이터 타입으로 정의하지 않았을 경우 주로 발생하는 에러 인것 같다. 확인해보니 나의 상황에도 맞았다.

STRING타입

FK로 사용하려는 post_id는 string타입인반면, PK로 사용하려는 posts테이블은 id는 int타입이다. 

INTEGER타입

다르다는 것을 알 수 있다. 그래서 string타입을 int타입으로 변경해 주었다.

그랬더니 npx sequelize-cli db:migrate 명령어가 잘혀서 에러발생 문제를 해결할 수 있었다.

 

#배운점 및 결론

-FK와 PK의 데이터타입은 같아야한다.

-솔로개발시에는 원래 쓰던 방식인 모델과 마이그래이션파일을 직접수정하는것이 편하고 빠르다.

-협업시나 배포중인 서비스에서는 절대적으로 sequelize migration:create –name addcolumn 명령어로 column추가 해야한다.

반응형