将元素与pymongo一起插入一系列嵌套模型mongodb

发布于 2025-02-03 08:44:57 字数 4117 浏览 4 评论 0原文

最近,我坚持将元素插入由父文档保存的数组中。 基本上,我的型号代表一列可以拥有许多货车的火车。货车是容纳货车的阵列。

这是

rom typing import Optional,Union

from pydantic import BaseModel, EmailStr, Field

#Wagon Model
class Wagon(BaseModel):
    no: int = Field(...)
    wagon_code: str = Field(...)
    wagon_type: str = Field(...)
    passengers_on_board: int = Field(...)
    max_capacity: int = Field(...)
    weight: float = Field(...)
    dimension: tuple  = Field(...)

    class Config:
        schema_extra = {
            "example": {
                "no": 3,
                "wagon_code": "GA151-03",
                "wagon_type": "Penumpang",
                "passengers_on_board": 40,
                "max_capacity":80,
                "weight":1050.01,
                "dimension": (20.62,9.91,4.15)
            }
        }

class UpdateWagon(BaseModel):
    no: Optional[int] 
    wagon_code: Optional[str]
    wagon_type: Optional[str]
    passengers_on_board: Optional[int]
    max_capacity: Optional[int]
    weight: Optional[float]
    dimension: Optional[tuple]
    
    class Config:
        schema_extra = {
            "example": {
                "no": 3,
                "wagon_code": "GA151-03",
                "wagon_type": "Penumpang",
                "passengers_on_board": 64,
                "max_capacity":80,
                "weight":1050.01,
                "dimension": (20.62,9.91,4.15)
            }
        }


#Train Model
class Train(BaseModel):
    name: str = Field(...)
    no: str = Field(...)
    first_station: str = Field(...)
    last_station: str = Field(...)
    from_: str = Field(...)
    to_: str = Field(...)
    current_station: str = Field(...)
    position: Optional[tuple]
    wagons: Union[list[Wagon], None] = None

    class Config:
        schema_extra = {
            "example": {
                "name": "Gajayana",
                "no": "GA-151",
                "first_station": "Malang - Kota Baru",
                "last_station": "Jakarta - Gambir",
                "from_":"Malang - Kota Baru",
                "to_":"Malang - Kota Lama",
                "current_station":"Malang - Kota Baru",
                "position": (2.12,2.12),
                "wagons" : [],
                }
        }

class UpdateTrain(BaseModel):
    name: Optional[str]
    no: Optional[str]
    first_station: Optional[str]
    last_station: Optional[str]
    from_: Optional[str]
    to_: Optional[str]
    current_station: Optional[str]
    position: Optional[tuple]
    wagons: Optional[list]

    class Config:
        schema_extra = {
            "example": {
                "name": "Gajayana",
                "no": "GA-151",
                "first_station": "Malang - Kota Baru",
                "last_station": "Jakarta - Gambir",
                "from_":"Malang - Kota Lama",
                "to_":"Kepanjen",
                "current_station":"Malang - Kota Baru",
                "position": (2.08,2.16),
                "wagons": [],
            }
        }

我使用arrayfilters将新创建的货车附加到火车上的数据库模型。但是,我没有运气来附加模型,但是如下功能所示,创建了一辆新的货车。

async def add_wagon(train_no: str,wagon_data: dict) -> dict:
    wagon = await wagon_collection.insert_one(wagon_data)
    new_wagon = await wagon_collection.find_one({"_id": wagon.inserted_id})
    train = await train_collection.find_one({"no": train_no})
    if train:
        train_collection.update_one({"no": train_no},{"$set":{"wagons.$[element]":new_wagon}},array_filters=[{"element":{"$exists":"false"}}],upsert=True)
    return wagon_helper(new_wagon)

该型号用作FastApi的API。上面的操作是使用PUT方法与路线进行的,如下所示。

@router.put("{train_no}/wagons/", response_description="Wagon data added into the database")
async def add_wagon_data(train_no: str,wagon: Wagon = Body(...)):
    wagon = jsonable_encoder(wagon)
    new_wagon = await add_wagon(train_no,wagon)
    return ResponseModel(new_wagon, "Wagon added successfully")

我的arrayfilters是错误的吗?还是我使用$的方式是确切的平等匹配是不正确的?

Recently I stuck on inserting an element into an array that held by a parent document.
Basically, my model represents a train that can have many wagons. The wagons is an array that hold a wagon.

Here is my database model

rom typing import Optional,Union

from pydantic import BaseModel, EmailStr, Field

#Wagon Model
class Wagon(BaseModel):
    no: int = Field(...)
    wagon_code: str = Field(...)
    wagon_type: str = Field(...)
    passengers_on_board: int = Field(...)
    max_capacity: int = Field(...)
    weight: float = Field(...)
    dimension: tuple  = Field(...)

    class Config:
        schema_extra = {
            "example": {
                "no": 3,
                "wagon_code": "GA151-03",
                "wagon_type": "Penumpang",
                "passengers_on_board": 40,
                "max_capacity":80,
                "weight":1050.01,
                "dimension": (20.62,9.91,4.15)
            }
        }

class UpdateWagon(BaseModel):
    no: Optional[int] 
    wagon_code: Optional[str]
    wagon_type: Optional[str]
    passengers_on_board: Optional[int]
    max_capacity: Optional[int]
    weight: Optional[float]
    dimension: Optional[tuple]
    
    class Config:
        schema_extra = {
            "example": {
                "no": 3,
                "wagon_code": "GA151-03",
                "wagon_type": "Penumpang",
                "passengers_on_board": 64,
                "max_capacity":80,
                "weight":1050.01,
                "dimension": (20.62,9.91,4.15)
            }
        }


#Train Model
class Train(BaseModel):
    name: str = Field(...)
    no: str = Field(...)
    first_station: str = Field(...)
    last_station: str = Field(...)
    from_: str = Field(...)
    to_: str = Field(...)
    current_station: str = Field(...)
    position: Optional[tuple]
    wagons: Union[list[Wagon], None] = None

    class Config:
        schema_extra = {
            "example": {
                "name": "Gajayana",
                "no": "GA-151",
                "first_station": "Malang - Kota Baru",
                "last_station": "Jakarta - Gambir",
                "from_":"Malang - Kota Baru",
                "to_":"Malang - Kota Lama",
                "current_station":"Malang - Kota Baru",
                "position": (2.12,2.12),
                "wagons" : [],
                }
        }

class UpdateTrain(BaseModel):
    name: Optional[str]
    no: Optional[str]
    first_station: Optional[str]
    last_station: Optional[str]
    from_: Optional[str]
    to_: Optional[str]
    current_station: Optional[str]
    position: Optional[tuple]
    wagons: Optional[list]

    class Config:
        schema_extra = {
            "example": {
                "name": "Gajayana",
                "no": "GA-151",
                "first_station": "Malang - Kota Baru",
                "last_station": "Jakarta - Gambir",
                "from_":"Malang - Kota Lama",
                "to_":"Kepanjen",
                "current_station":"Malang - Kota Baru",
                "position": (2.08,2.16),
                "wagons": [],
            }
        }

I was using arrayFilters to attach the newly created wagon to the train. However, I got no luck to attach the model but a new wagon was created as shown in the function below.

async def add_wagon(train_no: str,wagon_data: dict) -> dict:
    wagon = await wagon_collection.insert_one(wagon_data)
    new_wagon = await wagon_collection.find_one({"_id": wagon.inserted_id})
    train = await train_collection.find_one({"no": train_no})
    if train:
        train_collection.update_one({"no": train_no},{"$set":{"wagons.$[element]":new_wagon}},array_filters=[{"element":{"$exists":"false"}}],upsert=True)
    return wagon_helper(new_wagon)

The model was served as an API with FASTAPI. The operation above was done using PUT method with the route as shown below.

@router.put("{train_no}/wagons/", response_description="Wagon data added into the database")
async def add_wagon_data(train_no: str,wagon: Wagon = Body(...)):
    wagon = jsonable_encoder(wagon)
    new_wagon = await add_wagon(train_no,wagon)
    return ResponseModel(new_wagon, "Wagon added successfully")

Is my arrayFilters is wrong ? or is the way I use $exists as exact equality match is incorrect ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

初雪 2025-02-10 08:44:57

事实证明,我认为太复杂了。使用$ pushupsert = true解决问题。

async def add_wagon(train_no: str,wagon_data: dict) -> dict:
    wagon = await wagon_collection.insert_one(wagon_data)
    new_wagon = await wagon_collection.find_one({"_id": wagon.inserted_id})
    train = await train_collection.find_one({"no": train_no})
    if train:
        train_collection.update_one({"no": train_no},{"$push":{"wagons":new_wagon}},upsert=True)
    return wagon_helper(new_wagon)

It turns out I was thinking too complicated. USing $push with upsert=True solve the problem.

async def add_wagon(train_no: str,wagon_data: dict) -> dict:
    wagon = await wagon_collection.insert_one(wagon_data)
    new_wagon = await wagon_collection.find_one({"_id": wagon.inserted_id})
    train = await train_collection.find_one({"no": train_no})
    if train:
        train_collection.update_one({"no": train_no},{"$push":{"wagons":new_wagon}},upsert=True)
    return wagon_helper(new_wagon)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文