BeanieODM / beanie

Asynchronous Python ODM for MongoDB
http://beanie-odm.dev/
Apache License 2.0
1.91k stars 201 forks source link

Creating Document with Relation Requires All Parent Fields Instead of Just ID #310

Closed rgajason closed 1 year ago

rgajason commented 1 year ago

When used with FastAPI, all parent required fields become child required fields when creating a new document. For example:

Models

from beanie import Document, Indexed, Link

class Organization(Document):
    slug: Indexed(str, unique=True)

    class Settings:
        name = "github-organization"
        use_revision = True

class Repository(Document):
    organization: Link[Organization]
    name: Indexed(str, unique=True)

    class Settings:
        name = "github-repository"
        use_revision = True

Routers

from fastapi import APIRouter

from .models import Organization, Repository

router = APIRouter()

@router.post(
    "/organization",
    response_description="Add a new GitHub Organization",
    response_model=Organization,
)
async def create_organization(organization: Organization):
    await organization.create()
    return organization

@router.post(
    "/repository",
    response_description="Add a new GitHub Repository",
    response_model=Repository,
)
async def create_repository(repository: Repository):
    await repository.create()
    return repository

I can create an Organization by POSTing the following:

{
  "slug": "roman-right"
}

Let's say that generated a Mongo object ID of 62de9ecf2fa3d30007e3b5ce.

However, I cannot create a Repository with just the following:

{
  "organization": {
    "id": "62de9ecf2fa3d30007e3b5ce"
  },
  "name": "beanie"
}

That results in 422, unprocessable entity, with details that the Organization SLUG is required. I have tried the a few variations - id, _id, and also specifying organization as a string (the ID) vs an object (dictionary) - all with the same 422 error and similar messages.

Specifying any string for slug seems to work. For example:

{
  "organization": {
    "id": "62de9ecf2fa3d30007e3b5ce",
    "slug": ""
  },
  "name": "beanie"
}

(Repository document created as expected with link to correct Organization document)

It would seem to just be a parameter validating issue (required parent fields are required parameters even though only the id is used).

roman-right commented 1 year ago

Hey. Thank you for the report. This is an important one. I'll pick it up asap

rgajason commented 1 year ago

Glad you are back!

roman-right commented 1 year ago

Please try 1.11.9

rgajason commented 1 year ago

Thank you very much! I think we can call this one resolved. I'm able to POST data such as:

{
  "organization": "62de9ecf2fa3d30007e3b5ce",
  "name": "beanie"
}

...and the document is successfully created as expected.

The auto-generated documentation doesn't reflect this, but I can easily override.

Thanks again!

xykylikuf001 commented 1 year ago

Hi last time I start use benie odm, and I find it it great.

xykylikuf001 commented 1 year ago

It is possible make relations like on sqlalchemy:

class ProductType(Base):
name = sa.Column(sa.String(255), nullable=False, default='')
dimension_id = sa.Column(sa.Integer,
sa.ForeignKey('dimension.id', ondelete='RESTRICT', name='fx_product_type_dimension'),
nullable=False)

dimension = relationship('Dimension', )
xykylikuf001 commented 1 year ago

Thanks

rgajason commented 1 year ago

The documentation seek is here: https://roman-right.github.io/beanie/tutorial/relations/