inflearn logo
강의

講義

知識共有

配信アプリはどのように私の周りのグルメを見つけるのですか?

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

95

jahy53522475

投稿した質問数 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

communityai8509

안녕하세요, 인프런 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

jahy53522475

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

jahy53522475

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

recordable07111249

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

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

작업형 1 유형 부분

0

9

1

수강평 이벤트

0

16

2

순위가 동률일 때의 처리에 대해 질문드립니다.

0

10

2

작업형 1 (삭제예정, 구 버전)

0

28

2

강의노트는 어디있나요?

0

17

1

노션 학습 자료 권한 요청

0

15

1

수강기간 연장 문의드립니다.

0

20

1

2유형 레이블 인코딩 VS 원핫 인코딩

0

22

3

part2강의 문의사항입니다.

0

19

2

수강기간 연장 문의드립니다.

0

26

1

인덱스 슬라이싱

0

27

2

코드를 첨부해야하는 이유가 있나요?

0

20

2

소리가 겹쳐서 들려요

0

20

2

데스크톱과 노트북 연결

0

26

1

dict, zip

0

21

2

노션 : 파트3번 링크와 권한 , 파트4번 권한요청, 파트 5번도 미리 요청 드립니다.

0

27

4

6-6 실습 문의

0

23

2

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

0

59

1

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

0

105

2

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

0

137

2

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

0

281

2

odm 관련

0

451

3

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

0

567

1

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

3

2213

3