티스토리 뷰

반응형

지난 시간에 Gorm과 MariaDB를 연동해보았었는데요, 아직 안 보신 분은 빠르게 아래 글을 읽고 오시고 시작하도록 하겠습니다.

https://hero-space.tistory.com/138

 

Go와 Database 연동은 Gorm으로 시작!

백엔드 서버를 개발 할때, 데이터의 저장은 DB를 연동해서 하는 것이 일반적인데요. DB의 종류도 SQL로 할 꺼냐, NoSQL로 할꺼냐의 근본적인 결정도 있지만 SQL의 경우 데이터의 모델을 정의하고 이

hero-space.tistory.com

오늘은 Migration에 대해서 설명하면서 진행해보고 진행하면서 발생한 이슈에 대해서 설명드리도록 하겠습니다.

AutoMigration 이 머지?

DB라는 것은 서비스를 운영하면서 굉장히 중요한 요소입니다. 따라서 DB를 이중화 하는 작업들은 필수적으로 아키텍쳐를 작성하는데 있어서 필수적인 요소인데요. 뿐만아니라 개발할때 쓰는 DB와 프로덕션에서 사용하는 DB도 나뉘어서 사용합니다. 개발 중에는 DB의 스키마들이 추가될 수도 있기 때문인데요. RDB를 사용하는 경우 이런 가감되는 스키마는 굉장히 크리티컬 합니다. 물론 쉽사리 가감하진 않겠지만요. 

이렇게 중요한 요소인 DB를 로컬에 테이블을 만드는 것도 한두개가 아니면 수작업으로 하기에도 휴먼에러가 발생할 수도 있고 실 데이터도 조금 넣어봐야 테스터블한 DB 상태가 되기 때문에 테스터블한 DB를 로컬 개발환경에 구축하는 일은 개발 속도를 올려주는 필요한 일입니다. Gorm에서도 이러한 Auto Migration을 지원하고 있는데요, 아래 코드 한줄로 가능합니다.

db.AutoMigrate(&models.User{}, &models.Group{}, &models.Customer{}, &models.Sleep{}, &models.Device{}, &models.Prescription{}, &models.Reason{})

 

코드를 보시면 models 아래 User, Group, Customer 등등이 구성되어 잇는 것은 각각이 테이블이므로 테이블을 모델로 정의 해주는 작업은 먼저 필요하겠죠. 보는 것과 같이 저는 이렇게 여러가지의 테이블을 한번에 생성해야 하기 때문에 손으로 직접 하는 것은 굉장한 수고가 듭니다. 그럼 모델부터 먼저 만들어 볼까요?

제가 사용할 주요 키워드는 아래와 같습니다.

  • auto_increment
  • primary_key
  • foreignKey
  • not null
  • unique
  • type
  • size

 

Auto Migration을 진행시 트러블 슈팅

자, 이제 모델을 아래와 같이 작성하고 Migration을 시도해보도록 하겠습니다.

1. Primary Key 지정안됨

type User struct {
	ID           int    `json:"userId" gorm:"column:user_id;primaryKey;autoIncrement:True;not null"`
	Email        string `json:"email" gorm:"column:user_email" firestore:"email"`
	Name         string `json:"name" gorm:"column:user_name" firestore:"name"`
	Organization string `json:"organization" gorm:"column:organization" firestore:"organization"`
	Tag          string `json:"tag" gorm:"column:tag" firestore:"doctorId"`
	CreatedAt    int    `json:"createdAt" gorm:"column:created_at" firestore:"createdAt"`
	UpdatedAt    int    `json:"updatedAt" gorm:"column:updated_at" firestore:"updatedAt"`
}

실제 table을 봐보니 ID의 경우 primaryKey가 반영되지 않았고, not null만 지정되었는데요. Gorm 공식문서에 나온대로 했으나 되지 않았는데요.

https://gorm.io/docs/composite_primary_key.html

 

Composite Primary Key

Set multiple fields as primary key creates composite primary key, for example: type Product struct { ID string `gorm:"primaryKey"` LanguageCode string `gorm:"primaryKey

gorm.io

여러가지 시도 끝에 해결책은, AUTO_INCREMENT;PRIMARY_KEY로 작성해야 정상적으로 동작되었습니다.

`json:"userId" gorm:"column:user_id;AUTO_INCREMENT;PRIMARY_KEY;not null"`

아마도 Gorm 자체에서 버그일 수도 있어서 제가 사용하는 버전보다 높은 버전은 쓰시는 분들은 수정되었을 수 있으니 확인해보시기 바랍니다.

2. int(13) 지정 안됨

분명 int 타입을 지정하고 사이즈를 13으로 넣었으나 반영되지 않았는데요, 디버깅해보니, string 타입에서 size는 쿼리에 반영되나 int의 size는 쿼리에 반영하지 않음을 알 수 있었습니다. 다만, MariaDB 직접 접속해서 테이블 생성시 int(13)은 정상적으로 동작합니다.

type User struct {
	ID           int    `json:"userId" gorm:"column:user_id;AUTO_INCREMENT;PRIMARY_KEY;not null"`
	Email        string `json:"email" gorm:"column:user_email;size:100" firestore:"email"`
	Name         string `json:"name" gorm:"column:user_name;size:100" firestore:"name"`
	Organization string `json:"organization" gorm:"column:organization;size:100" firestore:"organization"`
	Tag          string `json:"tag" gorm:"column:tag;size:100" firestore:"doctorId"`
	CreatedAt    int    `json:"createdAt" gorm:"column:created_at;type:int(13)" firestore:"createdAt"`
	UpdatedAt    int    `json:"updatedAt" gorm:"column:updated_at;type:int(13)" firestore:"updatedAt"`
}

여러 시도를 해본 결과 int(13) 앞에 type이라는 키워드를 같이 분여줌으로써 int 이후 지정하고자하는 사이즈대로 테이블이 반영되서 생성됨을 알 수 있었습니다.

3. bool 지정안되고 tinyint(1)로 됨

bool이나 tinyint나 크게 다르지 않아 보이지만 bool을 지정했음에도 tinyint로 타입이 지정되서 테이블이 생성되었었는데요. 이는 MariaDB를 직접 접속해서 시도해봐도 동일했습니다. 그래서 검색해보니 bool과 tinyint는 같은것으로 사용하고 있어 문제가 되지 않음을 확인했습니다.

https://mariadb.com/kb/en/boolean/

 

BOOLEAN

Synonym for TINYINT(1).

mariadb.com

 

Auto Migration의 서두에 언급한 것처럼 여러 목적이 있지만, 테이블 생성을 처음부터 다시하기 귀찮을때, 또는 데이터가 가득들어있는데 이를 다른 곳에 초기화해서 만들때 유용하게 사용할 수 있는데요. 이런 기능들은 니즈가 있기때문에 클라우드에서 기본적으로 제공하기도 합니다. 이를테면 DB를 복제한다던지, 하는 것 처럼요. 직접할 수 도 있지만 클라우드 서비스를 사용하면 좀더 중요한 데이터 베이스를 잘 관리할 수 도 있으니, 단순히 DB를 구축할 때 ERD만을 보지말고 거시적인 관점에서 아키텍쳐를 잡아보는 것이 중요합니다. 앞으로 아키텍쳐 관련해서도 카테고리를 잡아서 글을 기술할 예정인데 그 때 또 다시 자세한 이야기를 다뤄보도록 하겠습니다.

 

반응형
댓글