SeaQL / sea-orm

🐚 An async & dynamic ORM for Rust
https://www.sea-ql.org/SeaORM/
Apache License 2.0
6.94k stars 483 forks source link

Panic on `load_many` call with different column name on primary key #1870

Open DMaxter opened 11 months ago

DMaxter commented 11 months ago

Description

I'm trying to use load_many to load the many side of multiple entities. However, if the many-side structure has the column name different from the struct name, and it is a primary key, it panics, as it tries to obtain the parameter through the column name and not through the struct parameter.

As an example, this is a many side of a relation:

#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(table_name = "stock")]
pub struct Model {
    #[sea_orm(primary_key, auto_increment = false)]
    pub bakery_id: i32,
    #[sea_orm(primary_key, column_name = "cake_name")]
    pub cake_id: String,
    pub amount: i32,
}

I receive a panic message like

thread 'main' panicked at /home/dmaxter/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sea-orm-0.12.3/src/query/loader.rs:360:37:
Failed at mapping string to column A:1
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

With deeper debugging, I found out that this is triggered by this line: https://github.com/SeaQL/sea-orm/blob/0.12.3/src/query/loader.rs#L226

For this specific case, I found out that here the value is cake_name while the model given only has cake_id, not cake_name property

Steps to Reproduce

  1. Create a postgres database named bakery
  2. Fill it with the data on db.sql
  3. Run the reproducer

Expected Behavior

Obtaining the many side

Actual Behavior

Panic

Reproduces How Often

Always

Workarounds

None, besides renaming the columns to match the model parameters (however this might not be possible, as is the case, because a migration from another platform is happening)

Reproducible Example

reproducer.zip

Versions

├── sea-orm v0.12.3 │ ├── sea-orm-macros v0.12.3 (proc-macro) │ │ ├── sea-bae v0.2.0 (proc-macro) │ ├── sea-query v0.30.1 │ ├── sea-query-binder v0.5.0 │ │ ├── sea-query v0.30.1 (*)

tyt2y3 commented 6 months ago

Thank you for the investigation. I am confident that this is fixable, although can you illustrate the problem by showing the examples of:

  1. what works
  2. what doesn't work
  3. the workaround that can make it work
DMaxter commented 5 months ago

I don't remember this issue very well, but I think this applies to one-to-many relationships

But what works is not using column_name at all (so, the struct field should match what is defined in the database) What doesn't work is using column_name as described above

The workaround was to not use column_name