SeaQL / sea-orm

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

columns with "select_as" attribute are not found and mapped to the model #1558

Open mohs8421 opened 1 year ago

mohs8421 commented 1 year ago

Description

when trying to use the "select_as" attribute like shown here:

#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
#[sea_orm(table_name = "baker")]
pub struct Model {
    #[sea_orm(primary_key)]
    pub id: i32,
    pub name: String,
    pub contact_details: Json,
    #[sea_orm(column_type = "Time", select_as = "CHAR", nullable)]
    pub working_time: Option<String>,
    pub bakery_id: Option<i32>,
}

it will not be possible to actually use the model features for that column, as it will not be properly mapped to the field. A query generated by that will look like this:

SELECT `baker`.`id`,
        `baker`.`name`, 
        `baker`.`contact_details`,
        CAST(`baker`.`working_time` AS CHAR),
        `baker`.`bakery_id`
FROM `baker`
WHERE `baker`.`id` = 1
LIMIT 1

Steps to Reproduce

  1. Declare a column to select_as something differing
  2. Try to insert into the database (postgres might already fail at this step)
  3. Select the new record from the database and check if the inserted value matches with the expected

Expected Behavior

The query should have an alias for the cast column, the value should be mapped

Actual Behavior

The value does not get mapped

Reproduces How Often

always

Workarounds

This was found while trying to get a workaround to the Time value in use not being able to go higher than 23:59:59. Would have actually preferred to be able to store a Duration.

Versions

0.11

mohs8421 commented 1 year ago

Diff for example:

Index: tests/common/bakery_chain/schema.rs
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/tests/common/bakery_chain/schema.rs b/tests/common/bakery_chain/schema.rs
--- a/tests/common/bakery_chain/schema.rs   (revision 162303cd0db7f572fd914f1851d5c1a6dfd2c346)
+++ b/tests/common/bakery_chain/schema.rs   (date 1679380125724)
@@ -52,6 +52,7 @@
                 .json()
                 .not_null(),
         )
+        .col(ColumnDef::new(baker::Column::WorkingTime).time())
         .col(ColumnDef::new(baker::Column::BakeryId).integer())
         .foreign_key(
             ForeignKey::create()
Index: tests/common/bakery_chain/baker.rs
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/tests/common/bakery_chain/baker.rs b/tests/common/bakery_chain/baker.rs
--- a/tests/common/bakery_chain/baker.rs    (revision 162303cd0db7f572fd914f1851d5c1a6dfd2c346)
+++ b/tests/common/bakery_chain/baker.rs    (date 1679379992794)
@@ -7,6 +7,8 @@
     pub id: i32,
     pub name: String,
     pub contact_details: Json,
+    #[sea_orm(column_type = "Time", select_as = "CHAR", nullable)]
+    pub working_time: Option<String>,
     pub bakery_id: Option<i32>,
 }

Index: tests/crud/create_baker.rs
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/tests/crud/create_baker.rs b/tests/crud/create_baker.rs
--- a/tests/crud/create_baker.rs    (revision 162303cd0db7f572fd914f1851d5c1a6dfd2c346)
+++ b/tests/crud/create_baker.rs    (date 1679380652687)
@@ -28,6 +28,7 @@
         name: Set("Baker Bob".to_owned()),
         contact_details: Set(serde_json::json!(baker_bob_contact)),
         bakery_id: Set(Some(bakery_insert_res.last_insert_id)),
+        working_time: Set(Some("27:30:00".to_owned())),
         ..Default::default()
     };
     let res = Baker::insert(baker_bob)
@@ -43,6 +44,7 @@
     assert!(baker.is_some());
     let baker_model = baker.unwrap();
     assert_eq!(baker_model.name, "Baker Bob");
+    assert_eq!(baker_model.working_time, Some("27:30:00".to_owned()));
     assert_eq!(
         baker_model.contact_details["mobile"],
         baker_bob_contact.mobile