inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

배달앱은 어떻게 내 주변의 맛집을 찾을까?

test.sh 실행시 missing arg 에러(_id)가뜹니다.

105

전재현

작성한 질문수 1

0

@dataclasses.dataclass(kw_only=True)
class BaseDocument:
    _id: ObjectId

    @property
    def id(self) -> ObjectId:
        return self._id

@dataclasses.dataclass
class ShopDeliveryAreaSubDocument(BaseDocument):
    poly: GeoJsonPolygon


@dataclasses.dataclass
class ShopDocument(BaseDocument):
    name: str
    category_codes: list[CategoryCode]
    delivery_areas: list[ShopDeliveryAreaSubDocument]

##test_shot_colleciton.py

async def test_shop_insert_one() -> None:
    # Given
    name = "치킨집"
    category_codes = [CategoryCode.CHICKEN]
    # 여기서 _id 값을 명시하지않아 에러가 나는것으로 보임.
    delivery_areas = [
        ShopDeliveryAreaSubDocument(
            poly=GeoJsonPolygon(coordinates=[[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]]]),
        )
    ]

 

에러코드

34 files left unchanged.
OK
Starting isort
Skipped 2 files
OK
Starting mypy
app/entities/collections/shop/shop_collection.py:51: error: Missing named argument "_id" for "ShopDeliveryAreaSubDocument"  [call-arg]
app/tests/entities/collections/shop/test_shop_collection.py:15: error: Missing named argument "_id" for "ShopDeliveryAreaSubDocument"  [call-arg]

 

BaseDocument 에는 _id : ObjectId 라는 attr이 항상 명시되도록 되어있는데 test 파일에는 명시가되어있지않아 나오는 에러같은데, 명시하지않아도 정상동작 되나요?? 아니면 Optional 값으로 주어야하는걸까요!?

 

감사합니다.

 

 

python mongodb FastAPI

답변 1

0

인프런 AI 인턴

안녕하세요, 인프런 AI 인턴입니다.

전재현님께서 질문하신 내용은 Python의 dataclass와 관련된 에러입니다. BaseDocument_id 필드는 필수적으로 지정되어야 하는데, ShopDeliveryAreaSubDocument 객체를 생성할 때 _id를 명시하지 않아서 발생한 문제로 보입니다.

우선, _id 필드가 BaseDocument에서 필수입니다. 따라서 해당 객체를 생성할 때 이 값을 제공해야 합니다. 만약 자동으로 생성하고 싶다면, Python의 dataclasses.fielddefault_factory 기능을 활용하여 옵션으로 처리할 수 있습니다.

예를 들어, ObjectId가 자동으로 생성되도록 하려면 bson.objectid.ObjectId의 생성자 호출을 default_factory로 설정할 수 있습니다.

from bson import ObjectId
import dataclasses

@dataclasses.dataclass(kw_only=True)
class BaseDocument:
    _id: ObjectId = dataclasses.field(default_factory=ObjectId)

# 이렇게 기본값을 설정하면 생성 시 `_id`를 명시적으로 지정하지 않아도 자동으로 생성됩니다.

위와 같이 설정하면 ShopDeliveryAreaSubDocument를 생성할 때 _id 값이 자동 생성되어 명시하지 않아도 됩니다.

이와 관련한 자세한 내용은 다음 링크에서 확인할 수 있습니다: Python Dataclasses.

추가적으로 mypy의 에러는 _id가 예상되는 곳에 명시되지 않았기 때문에 발생합니다. 위와 같은 방법으로 기본값을 설정하면 이러한 에러를 방지할 수 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

0

전재현

id가 명시되지않아서 생기는 오류입니다만. 강의자료 test_code 에서는 _id에 대한 코드가 없더라구요. 제가 빠트린부분이 있는지 궁금합니다.

 

async def test_shop_insert_one() -> None:
    # Given
    name = "치킨집"
    category_codes = [CategoryCode.CHICKEN]
    delivery_areas = [
        ShopDeliveryAreaSubDocument(
            poly=GeoJsonPolygon(coordinates=[[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]]]),
        )
    ]

    # When
    shop = await ShopCollection.insert_one(name, category_codes, delivery_areas)
    # cursor = await ShopCollection._collection.find({})
    # results = await cursor.to_list(None)
    results = await ShopCollection._collection.find({}).to_list(None)

    # Then
    assert len(results) == 1
    result = results[0]
    assert result["_id"] == shop.id
    assert result["name"] == shop.name
    assert result["category_codes"] == ["chicken"]
    assert result["delivery_areas"] == [
        {"poly": {"type": "Polygon", "coordinates": [[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]]]}}
    ]

# test_code의  result["delivery_areas"] 부분에 _id를 명시하지 않아도 통과가 되는지 궁금합니다. _id값은 매번 변할텐데 명시하는게 가능한가요?

0

전재현

import pytest
import pytest_asyncio
from deepdiff import DeepDiff

from app.entities.category.category_codes import CategoryCode
from app.entities.collections.geo_json import GeoJsonPolygon
from app.entities.collections.shop.shop_collection import ShopCollection
from app.entities.collections.shop.shop_document import ShopDeliveryAreaSubDocument


async def test_shop_insert_one() -> None:
    # Given
    name = "치킨집"
    category_codes = [CategoryCode.CHICKEN]
    delivery_areas = [
        ShopDeliveryAreaSubDocument(
            poly=GeoJsonPolygon(coordinates=[[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]]]),
        )
    ]

    # When
    shop = await ShopCollection.insert_one(name, category_codes, delivery_areas)
    # cursor = await ShopCollection._collection.find({})
    # results = await cursor.to_list(None)
    results = await ShopCollection._collection.find({}).to_list(None)

    # Then
    assert len(results) == 1
    result = results[0]
    assert result["_id"] == shop.id
    assert result["name"] == shop.name
    assert result["category_codes"] == ["chicken"]
    # assert result["delivery_areas"] == [
    #     {"poly": {"type": "Polygon", "coordinates": [[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]]]}}
    # ]
    diff = DeepDiff(
        result["delivery_areas"],
        [{"poly": {"type": "Polygon", "coordinates": [[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]]]}}],
        ignore_order=True,
        exclude_regex_paths=r"root\[\d+\]\['_id'\]",
    )
    assert diff == {}

deepdiff 라이브러리를 이용해서 해결하긴했습니다만 BaseDocument 를 상속하고있는 ShopDelieveryAreaSubDocument 는 id 없이 생성이 되는지는 잘 모르겠습니다. ( 강의코드에서는 _id에 대한 default값이 없는것으로 보여서요!)

0

정승원

재현님 안녕하세요! ShopDeliveryAreaSubDocument 는 BaseDocument 를 상속하지 않습니다~!

상속하지 않기 때문에 _id 가 없어도 생성할 수 있습니다~

강의 자료

0

4

1

27:15 break 출력

0

9

1

kaggle notebook에 service key 설정이 누락된 것 같습니다

1

15

2

수업 노트가 안 보입니다.

0

19

1

Python formatter 설치

0

16

1

55강 파이썬에만있는 연산자들

0

20

2

55강의 파이썬에서만 있는 연산자들

0

20

2

주말에 실행할 경우 update_economic_data_in_background에 로직 변경 필요성

1

25

1

naver 글자 수집 오류 건

0

23

1

쥬피터 노트북이 실행이 안됩니다.

0

24

1

뒤로가기 버튼 같은 것이 있나요?

0

26

1

Replit 강의 자료가 안나와요

0

20

1

강의 연장 문의

0

28

1

프로그램 실행시간에 대한 질문

1

22

2

비중 및 매수 종목수 조정.

1

31

2

Claude api가 소식 동기화가 늦는 문제

1

41

2

[긴급요청2] 28강 동영상 오류(27강 음성 재생) 수정 예정일자를 알려주세요

0

25

1

아래 질문 내용 추가 질문 사항 입니다.

0

77

1

파이참을 이용해서 Python Interpreter 통해 라이브러리 설치가 안되는데 도움이 필요합니다.

0

123

2

캐시 구현에서 Redis - MongoDB 스코프

0

154

2

강사님께서 entity를 사용하신 이유가 궁금합니다

0

304

2

odm 관련

0

476

3

test.sh 파일 실행 후 에러 처리 방법

0

592

1

테스트를 실행했을 때 RuntimeError: Event loop is closed 에러가 발생합니다.

3

2249

3