sea-orm icon indicating copy to clipboard operation
sea-orm copied to clipboard

`into_json` uses field names set by `column_name`

Open junbl opened this issue 3 years ago β€’ 3 comments

Description

When getting data from into_json, the resulting Value uses the field names set by the #[sea_orm(column_name = "")] macro instead of the names of the fields in the struct.

I'm guessing that it just serializes the data directly from the database, without using the Model, since it can't necessarily be put into that structure. If so, maybe we could get access to some generated mapping between the field and column names so we can rename the columns manually?

Steps to Reproduce

  1. Prepare a query.
  2. Call into_json().
  3. Retrieve the models from the database.

Expected Behavior

I would expect

    Entity::find().into_json().one(&conn).await.unwrap().unwrap();

to be equal to

    serde_json::to_value(Entity::find().one(&conn).await.unwrap()).unwrap();

If this is intended behavior, I'd at least like to be able to configure it so that they do produce the same output.

Actual Behavior

The results from into_json use field names from column_name, while the results from into_model use the field names of the struct.

Reproduces How Often

Every time

Versions

─ sea-orm v0.9.1
β”œβ”€β”€ sea-orm-macros v0.9.1 (proc-macro)
β”œβ”€β”€ sea-query v0.26.2
β”‚   β”œβ”€β”€ sea-query-derive v0.2.0 (proc-macro)
β”‚   β”œβ”€β”€ sea-query-driver v0.2.0 (proc-macro)
β”œβ”€β”€ sea-strum v0.23.0
β”‚   └── sea-strum_macros v0.23.0 (proc-macro)

WSL Ubuntu 22.04 on Windows 11

Additional Information

https://github.com/e-rhodes/sea-orm-serialize-mre

junbl avatar Jul 21 '22 19:07 junbl

Hey @e-rhodes, these two isn't equivalent:

  1. Query result is directly mapped into a JSON. Without first deserializing into Model then serialized back into JSON. This is a performance optimization provided by SeaORM.
    Entity::find().into_json().one(&conn).await.unwrap().unwrap();
    
  2. Query result is deserialized into Model and then serialized into JSON.
    serde_json::to_value(Entity::find().one(&conn).await.unwrap()).unwrap();
    

Hence, if you want the resulting JSON key same as the name of model field. Please go with code snippet 2.

billy1624 avatar Jul 25 '22 08:07 billy1624

Makes sense. Unfortunately, this isn't an option since I'm dealing with custom selects and the structure isn't predictableβ€”so users will specify a field by one name and then see it in the result by another name. Hope I can find a workaround.

junbl avatar Jul 25 '22 14:07 junbl

Okay, I guess you can .map(|json| ...) then transform the key inside the JSON object

billy1624 avatar Jul 26 '22 04:07 billy1624

The idea is that there can be some other operations following find(), may be "group by" or "column as", so the fields are not predictable and they will not be the same as the model.

But - if you only want to convert the keys into camelCase, then you can write a small json transformer anyway. It doesn't have to be part of the ORM, although contribution is welcomed.

tyt2y3 avatar Feb 22 '23 04:02 tyt2y3