Flatten out struct fields on insertions
Is your feature request related to a problem? Please describe. If we have a struct with many fields which we want to insert to the database, we need to write out every field individually, this gets inconvenient and hard to maintain (removing/adding a field and column needs changing every query they're used in)
struct ManyFields {
assume: i64,
theres: i64,
many: i64,
}
async fn insert(db: &PgPool, fields: ManyFields) -> sqlx::Result<()> {
query!(
"INSERT INTO many_fields VALUES ($1, $2, $3)",
fields.assume,
fields.theres,
fields.many
).exec(db).await?;
Ok(())
}
Describe the solution you'd like
- The struct's field names have to match the column names, similar to
#[sqlx(FromRow)] - The query could:
- Ignore the fields that are unused (if struct as
foo, bar, bazfields and table/insertion hasfoo, barcolumns, it'd still be allowed), which lets us avoid creating new structs or taking fields by parameters, but also makes the function require more fields than actually used (which is very common in other code actually). - Require an exact match between fields and columns
- Ignore the fields that are unused (if struct as
- It would also ideally work with multiple structs, flattening each one's fields
struct ManyFields {
assume: i64,
theres: i64,
many: i64,
}
async fn insert(db: &PgPool, fields: ManyFields) -> sqlx::Result<()> {
query!("INSERT INTO many_fields VALUES ($1)", fields).exec(db).await?;
Ok(())
}
Describe alternatives you've considered
If required, this could be another function/macro, like how query and query_as are different
Additional context
This might help with making unnest() (which is currently required for multiple-row insertions) easier
#328 and sqlxinsert may be of interest also.
There is now a set of new macros in SeaQuery allowing you to write:
struct Item {
a: i32,
b: String,
c: u16,
}
let values = vec![
Item { a: 1, b: "2".to_owned(), c: 3 },
Item { a: 4, b: "5".to_owned(), c: 6 },
];
let mut sql;
let res = sea_query::sqlx::sqlite::query!(
sql = r#"INSERT INTO "glyph" ("aspect", "image", "font_size")
VALUES {..(values.a, values.b, values.c),}"#
).execute(pool).await?;
Ref: https://www.sea-ql.org/blog/2025-08-15-sea-query-raw-sql/#sqlx-integration