Gorm 쓰는게 어렵고 테이블 정의와 db 스키마를 어떻게 짜야할지 좀 알기 위해 문서화된 소스를 정리해보는 페이지

ref : https://gorm.io/docs/models.html

해당 기능이 gorm이 제공하는 건지, db가 제공하는 건지를 잘 구분하면서 학습할 것.

그때그때 찾아보면 되는 정보들은 정리하지 않는다. 시간이 그렇게 많지 않음. gorm이 데이터를 조작할 때 적용하는 fundamental rule들에 중점을 둔다.

1. 시작

2. CRUD 인터페이스

3. Association

4. tutorials

5. Advanced

  1. 하나의 데이터 (이하 gradePrice) 당 두 개의 struct가 각각 entity 층과 repository 층에 정의 됨.

    (이하 각각 GradePrice, GradePriceRepo)

  2. GradePrice에는 Grade entitiy가 통으로 들어있음. 포인터가 아닌 값으로

    이에 대한 이유를 명확히 알아야겠음. Join을 해야할 때가 있어서? 아니면 그냥 참조하니까?

    내 기억엔 join때문에 이렇게 넣은 것 같긴 한데 아마 후자인 것 같음.

    Join같은게 필요하다면 결국 새로운 type의 struct가 필요하고, 이는 controller단에서 선언해주면 될 것 같다. 이러면 의존 관계가 꼬일 일도 없는 것 같음.

  3. client가 요청을 보낼 때도 Grade 객체를 req.body에 한 depth 더 넣어서 보냄.

  4. copier.Copy가 데이터를 GradePrice에서 GradePriceRepo로 변환함.

    GradePriceRepo도 *Grade를 가지고 있기 때문에 있는 데이터만 Grade에 채움.

    그런데 여기서 GradePriceRepo의 GradeID는 값이 채워지지 않음. GradePrice에 그 값이 없으니까..

  5. 다른 db의 table을 참조하는 칼럼의 유효성을 검증

  6. 이제 데이터를 GradePrices table에 삽입하는데, 여기서 문제가 발생함.

  7. 만약 Grades Table을 참조하는 GradePrices Table에 데이터를 추가할 때, 대응하는 GradeID가 없다면, upsert가 일어난다.

    우선 Grades 테이블에 대응하는 GradeID (fk)를 가진 데이터 셋을 추가 한뒤, GradePrice table에 데이터셋을 추가함.

    여기서 끝나지 않음. ID는 auto increment라 정작 GradePrice의 GradeID와 동일한 값을 가진 Grade.ID 값을 가진 데이터셋이 생성되지도 않는다.

  8. gorm tag “-”를 entities.GradePrice에 추가 - 효과 없음

  9. Omit method 사용

    Omit method를 중간에 껴넣으면 참조되는 테이블까지 건드는건 막을 수 있다.

    현재로서는 가장 좋은 방법인 것 같음. 적어도 Omit 을 넣으면 외래키가 참조되는 테이블에 있는지는 체크해서 거를 수 있고, 참조되는 테이블에 없는 데이터셋을 새로 생성하는 것도 막을 수 있다.

    단 이 경우, 참조하는 테이블의 fk.ID값이 비게 되므로 외래키가 없다는 에러가 나온다. entities.Gradeprice struct에 entities.Grade를 통째로 넣어서 쓸거라면 데이터를 repository.GracePrice로 바꾸는 과정에서 추가적인 데이터 변환 과정이 필요할 것 같음.

    이 방식을 사용한다면 아마 외래키는 전부 수동으로 조정을 해야할 것 같다.