[python] Marshmallow를 사용하여 데이터간 관계 설정하기

Marshmallow는 파이썬에서 데이터 직렬화 및 역직렬화를 쉽게 처리할 수 있는 라이브러리입니다. 이 라이브러리는 데이터 직렬화를 위한 schema와 데이터 역직렬화를 위한 load/dump 함수를 제공합니다. Marshmallow는 데이터베이스 모델과의 관계 설정을 위해도 사용할 수 있습니다.

이번 예제에서는 Marshmallow를 사용하여 간단한 데이터베이스 모델 간의 관계를 설정하는 방법에 대해 알아보겠습니다.

설치

Marshmallow를 설치하려면 다음 명령을 실행합니다:

pip install marshmallow

예제

다음은 사용자(User)와 그룹(Group)이라는 두 개의 데이터베이스 모델이 있을 때, 이들 간의 다대다 관계를 Marshmallow를 이용하여 설정하는 예제입니다.

from marshmallow import Schema, fields, post_load

class User:
    def __init__(self, id, name, groups):
        self.id = id
        self.name = name
        self.groups = groups

class Group:
    def __init__(self, id, name, users):
        self.id = id
        self.name = name
        self.users = users

class UserSchema(Schema):
    id = fields.Int()
    name = fields.Str()
    groups = fields.Nested("GroupSchema", many=True, exclude=("users",))

class GroupSchema(Schema):
    id = fields.Int()
    name = fields.Str()
    users = fields.Nested(UserSchema, many=True, exclude=("groups",))

@post_load
def make_user(self, data, **kwargs):
    return User(**data)

@post_load
def make_group(self, data, **kwargs):
    return Group(**data)

user1_data = {
    "id": 1,
    "name": "John",
    "groups": [
        {
            "id": 1,
            "name": "Group 1"
        },
        {
            "id": 2,
            "name": "Group 2"
        }
    ]
}

user_schema = UserSchema()
user = user_schema.load(user1_data)

print(user.name)  # John
print(user.groups[0].name)  # Group 1
print(user.groups[1].name)  # Group 2

위의 예제에서는 User 클래스와 Group 클래스를 정의하고, 각 클래스의 인스턴스를 생성할 때 필요한 속성들을 지정하였습니다. 또한 UserSchema와 GroupSchema를 생성하여 각 모델과 직렬화할 스키마를 매핑하였습니다.

UserSchema와 GroupSchema에서는 각각 다른 모델과의 관계를 나타내는 필드도 정의할 수 있습니다. 이 예제에서는 User에 속한 그룹들(다대다 관계)와 Group에 속한 유저들(다대다 관계)을 나타내는 Nested 필드를 사용하였습니다. 그리고 exclude 옵션을 사용하여 순환 참조를 방지하였습니다.

데이터를 역직렬화할 때는 Schema의 load 함수를 호출하여 JSON 데이터를 모델 객체로 변환합니다. 이렇게 얻은 모델 객체를 통해 데이터를 다루고 출력할 수 있습니다.

결론

Marshmallow를 사용하면 복잡한 데이터베이스 모델 간의 관계를 쉽게 설정할 수 있습니다. Marshmallow는 데이터 직렬화 및 역직렬화 작업에 필요한 스키마와 함수들을 제공하므로, 개발자는 데이터 간의 관계를 명시적으로 표현하고 처리할 수 있습니다. 이를 통해 코드의 가독성과 유지보수성을 높일 수 있습니다.