외부 api를 통해서 가지고 온 데이터를 기반으로 서비스를 구성하기 위해 서비스가 제공하는 역할에 따라서 시나리오데 따라 DB구조를 먼저 정의하고,
추가될 수 있는 테이블을 고려해서 DB스키마를 구성하였다.
최종 데이터를 제공하기 위해서 간단하게 아래와 같은 테이블 구조가 필요했다.
데이터 베이스 스키마에는 서비스가 제공하는 데이터를 표현하기 위해서 1️⃣:1️⃣ 관계, 1️⃣:N 관계, M:N 관계를 모두 정의해주었다.
서비스 데이터 표현 방식은 외부 API에서 가져온 데이터를 하나씩 파싱
여러개의 데이터가 Serializing대상이 된다면 Many옵션을 주어 처리하고, 역참조 관계에 있는(source = foo_set 옵션을 주어 부모 테이블인 Mission Report에서 자식테이블의 데이터를 가져오기 위해 처리.
E의 Serializer를 정의한 후 save
를 오버라이딩 해서 연관 구조를 가진 데이터가 하나의 테이블로 엮어 저장될 수 있게 구현하였다.
E의 연관관계를 Instance
가 포함할 데이터 prefetch_realated
로 가져오고 난 후
Mission, Robot, Action을 표현할 때 참조한 컬럼(id)을 표현하지 않고 참조 컬럼의 인스턴스를 표현하기 위해서 to_representation
을 오버라이딩.
-> to_representation
으로 Instance를 표현하는 방법을 몰라서 맞는 쿼리와 Serializer구조를 만들었음에도 불구하고 결과에서는 값들이 나타나지 않거나 Id값 만이 표현되는 현상을 해결할 수 있었다. ⭐️
만약 오버라이딩 하지 않는다면 ID가 표현됨
서비스 데이터를 제공하기 위해 연관관계 테이블의 데이터를 표현하는 과정에 Instance에 담긴 데이터를 표현하기 위해 Query작성, 시리얼라이저 작성 과정을 이해하기 좋은 예제였고
서비스를 전체적인 관점에서 파악하여야 그에 맞는 DB 스키마를 구성할 수 있고 확장이 용이한 형태로 설계할 수 있다.
이전에 비해 좁은 시야에서 보다 넓은 시야에서 구조를 먼저 생각하고 구현할 수 있는 경험이었다.
외부 API에서 얻은 데이터 바탕으로 제공 할 서비스에 맞게 단일 테이블, 연관 테이블구조를 가진 DB스키마를 구성하면서 시행착오를 겪었는데
→ ManyToMany, OneToMany, OneToOne관계를 가진 테이블 구조를 비즈니스 상황에 맞게 설계할 수 있다.
이는 Model에서 null, brank를 True로 세팅하고 Serializer에서 serialize 과정에서 parsing할 데이터를 모델과 맞추기 위해 extra_kwargs 속성, serialize 필드에서 required를 False로 바꾸어 주면 됐다.
You'll normally want to ensure that you've set an appropriate related_name
argument on the relationship, that you can use as the field name. For example:
class Track(models.Model):
album = models.ForeignKey(Album, related_name='tracks', on_delete=models.CASCADE)
...
If you have not set a related name for the reverse relationship, you'll need to use the automatically generated related name in the fields
argument. For example:
class AlbumSerializer(serializers.ModelSerializer):
class Meta:
fields = ['track_set', ...]