FastAPI-JSONAPI icon indicating copy to clipboard operation
FastAPI-JSONAPI copied to clipboard

sparse fields parameter for include causes pydantic error

Open srepmub opened this issue 7 months ago • 1 comments

thanks for the awesome project. most of the things I have tried are working - like magic! I did run into a few minor issues though. before diving into the code myself, perhaps you guys already have an idea of what might be the problem there.

for example, the following works fine:

/voorschrijfproduct/51/?include=generiekproduct

this shows 'naam' attributes for both types.

also the following works fine:

/voorschrijfproduct/51/?include=generiekproduct&fields[voorschrijfproduct]=naam

but not the following:

/voorschrijfproduct/51/?include=generiekproduct&fields[voorschrijfproduct]=naam&fields[generiekproduct]=naam

this gives errors (one for each attribute besides 'naam' it seems):

[SQL: SELECT generiekproduct.verval_datum AS generiekproduct_verval_datum 
FROM generiekproduct 
WHERE generiekproduct.id = %s]
[parameters: [{'pk_1': 112615}]]
(Background on this error at: https://sqlalche.me/e/20/xd2s) [type=get_attribute_error, input_value=<model.Generiekproduct object at 0x751c74ac30e0>, input_type=Generiekproduct]
    For further information visit https://errors.pydantic.dev/2.10/v/get_attribute_error

so it looks like pydantic expects the other attributes to still be there, even though only 'naam' comes from the database? (I see in another issue that you changed this recently - perhaps this is caused by not getting everything from the database anymore?)

happy to provide more information, or to try and create a test in your test set for this.

srepmub avatar Apr 18 '25 08:04 srepmub

the following test does something very similar, but it works:

test_api/test_api_sqla_with_includes.py::TestGetUsersList::test_select_custom_fields_with_includes

the difference seems to be that my test case includes a many-to-one relation, whereas this test case goes in the opposite direction.

when changing the test case to start from 'post' and include 'user' (so opposite direction) I get a similar pydantic error:

        url = app.url_path_for("get_post_list")
        user_1, user_2 = sorted((user_1, user_2), key=lambda x: x.id)
    
        user_2_post = await create_post(async_session, user_2)
        user_1_post = await create_post(async_session, user_1)
    
        queried_user_fields = "name"
        queried_post_fields = "title"
    
        params = QueryParams(
            [
                ("fields[user]", queried_user_fields),
                ("fields[post]", queried_post_fields),
                ("include", "user"),
            ],
        )
       response = await client.get(url, params=f"{params}")

leading to:

pydantic_core._pydantic_core.ValidationError: 2 validation errors for user_hidden_generationAttributesJSONAPI
E           age
E             Error extracting attribute: MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s) [type=get_attribute_error, input_value=<examples.api_for_sqlalch...bject at 0x7c9d28f84440>, input_type=User]
E               For further information visit https://errors.pydantic.dev/2.10/v/get_attribute_error
E           email
E             Error extracting attribute: MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/20/xd2s) [type=get_attribute_error, input_value=<examples.api_for_sqlalch...bject at 0x7c9d28f84440>, input_type=User]
E               For further information visit https://errors.pydantic.dev/2.10/v/get_attribute_error

srepmub avatar May 09 '25 13:05 srepmub