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

New Mapping options

Open ikrivosheev opened this issue 3 years ago • 10 comments
trafficstars

Motivation

A lot code in my projects is mapping SQL query result into rust struct and convert it to JSON string. I have a few suggestions on how to fix this situation.

Embeddable:

Example:


#[derive(FromQueryResult)]
struct Nested {
  n: String,
}

#[derive(FromQueryResult)]
struct Parent {
  p: String,
  #[sea_orm(embeddable)]
  n: Nested,
}

SQL query: SELECT p, n FROM table

We can reuse some fields in query result or we can convert two fields into nested struct.

Nested

#[derive(FromQueryResult)]
struct Nested {
  n: String,
}

#[derive(FromQueryResult)]
struct Parent {
  p: String,
  #[sea_orm(prefix="nested_")]
  nested: Nested,
}

SQL query: SELECT p, n as nested_n FROM table

We can mapping one to one into nested field.

Relationship

I have a small idea with this. We can create trait:

trait QuerySet<T> {...}

// Example T
#[derive(FromQueryResult)]
struct RelationResult {
  id: i32,
  name: String,
}

#[derive(FromQueryResult)]
struct ResultTable {
  id: i32,
  name: String,
}

#[derive(QuerySet)]
struct Result {
  table: ResultTable,
  #[sea(one_to_many="key_id")]
  keys: Vec<RelationResult>,
}

SQL example: SELECT id, name, key_id, keys.id, keys.name FROM table JOIN keys ON table.key_id = keys.id.

P.S. I didn't specifically talk about Model because it seems to me it would be very convenient to have a mechanism for mapping SQL query result two struct and after extend Model.

P.P.S. There are few implementation details yet, but if this functionality would be interesting I can implement the first two points and discuss the implementation of the last

ikrivosheev avatar May 16 '22 22:05 ikrivosheev

Actually I don't quite understand the difference between embeddable and nested. For "Relationship", I think it's somewhat close to what find_with_related does now?

I have a sense that the problem is more in the domain of "transforming from query result into json" that may not directly affect query execution?

tyt2y3 avatar May 17 '22 15:05 tyt2y3

@tyt2y3 different is

  1. embeddable in query is flat list in rust is nested struct (without prefix)
  2. nested this is embeddable with prefix in column name

Yes, it is close, but with some different:

  1. I can have more then one relationships
  2. I can set any key for relationship

ikrivosheev avatar May 17 '22 16:05 ikrivosheev

There are only two hard things in Computer Science: cache invalidation and naming things

I think I have some problems with the naming

ikrivosheev avatar May 17 '22 16:05 ikrivosheev

In more general terms: I want some features like in serde deserialization for more convenient mapping of query results to Rust struct.

ikrivosheev avatar May 17 '22 17:05 ikrivosheev

I think Embeddable and Nested are the same, the only difference is having column prefix or not

billy1624 avatar May 18 '22 11:05 billy1624

In Diesel, you can specify a ToSql and FromSql trait on your object. Thats the most flexible IMO, but I like the embedded solution for JSON. It might be error prone / annoying for users to have to redo this change every time the entities are generated, so maybe a solution like #[sea_orm(Nested)] would de preferable so the annotation can be preserved between generations.

Sytten avatar May 18 '22 18:05 Sytten

Any updates on this?

Sculas avatar Aug 17 '22 04:08 Sculas

@Sculas hello! Sorry for delay. I want to do some task in SeaQuery and after return to this issues.

ikrivosheev avatar Aug 20 '22 12:08 ikrivosheev

It seems like the #[serde(flatten)] in serde crate?

Goodjooy avatar Oct 05 '22 11:10 Goodjooy

Hey, I'm very interested in this feature (https://github.com/SeaQL/sea-orm/discussions/1797 for reference) Is it still planned?

SteelAlloy avatar Aug 08 '23 18:08 SteelAlloy