3

I have a class model using Pydantics. I try to supply my own ID but it gives me two id fields in the MongoDB database. The one I gave it and the one it makes automatically.

Here is the result of my post method:

here is the result of my post method

here is my class in models/articleModel.py:

class ArticleModel(BaseModel):
    _id: int
    title: str
    body: str
    tags: Optional[list] = None
    datetime: Optional[datetime] = None
    caption: Optional[str] = None
    link: Optional[str] = None
    
class Config:
    orm_mode = True
    allow_population_by_field_name = True
    arbitrary_types_allowed = True

here is my code for the post method in routers/article_router:

@router.post("/article/", status_code=status.HTTP_201_CREATED)
def add_article(article: articleModel.ArticleModel):
    article.datetime = datetime.utcnow()

    try:
        result = Articles.insert_one(article.dict())
        pipeline = [
            {'$match': {'_id': result.inserted_id}}
        ]
        new_article = articleListEntity(Articles.aggregate(pipeline))[0]
        return new_article
    except DuplicateKeyError:
        raise HTTPException(status_code=status.HTTP_409_CONFLICT,
                            detail=f"Article with title: '{article.id}' already exists")
SternK
  • 11,649
  • 22
  • 32
  • 46
  • 1
    Could it be because of Pydantic's [_Automatically excluded attributes_](https://docs.pydantic.dev/usage/models/#automatically-excluded-attributes)? – rickhg12hs Feb 19 '23 at 12:51
  • @rickhg12hs I don't think so. But I did solve it by converting it to a dictionary and adding a new key called _id. – Suha Karkhy Feb 19 '23 at 13:57
  • You may find [this answer](https://stackoverflow.com/a/71468967/17865804) helpful as well – Chris Mar 11 '23 at 08:21

1 Answers1

3

I had to change the articleModel to a dictionary and add a new key called _id.

@router.post("/article/", status_code=status.HTTP_201_CREATED)
def add_article(article: articleModel.ArticleModel):
    article.datetime = datetime.utcnow()
    
    article_new_id = article.dict()
    article_new_id['_id'] = article_new_id['id']
    del article_new_id['id']

    try:
        result = Articles.insert_one(article_new_id)
        pipeline = [
            {'$match': {'_id': result.inserted_id}}
        ]
        new_article = articleListEntity(Articles.aggregate(pipeline))[0]
        return new_article
    except DuplicateKeyError:
        raise HTTPException(status_code=status.HTTP_409_CONFLICT,
                            detail=f"Article with title: '{article.id}' already exists")
Roj
  • 995
  • 1
  • 8
  • 22