Skip to main content

insert

insert(&self, values: T) where T derives #[derive(SqlxInsert)] — a single-row INSERT built from every named field of T, in declaration order.

#[derive(SqlxInsert)]
pub struct UserValues {
pub username: String,
pub email: String,
}

async fn insert(&self, values: UserValues) -> sqlx::Result<UserRow>;

Void vs. row-returning​

The return type decides whether the written row is fetched back:

async fn insert(&self, values: EventValues) -> sqlx::Result<()>; // INSERT, nothing fetched back
async fn insert(&self, values: EventValues) -> sqlx::Result<EventRow>; // INSERT ... RETURNING *

Per-dialect SQL​

Postgres/SQLite: INSERT INTO "table" (cols...) VALUES ($1, ...) RETURNING * — one round-trip.

MySQL has no RETURNING. The row-returning form does INSERT → last_insert_id() → SELECT * FROM table WHERE {key} = ?. {key} comes from an optional struct-level attribute on the values struct, defaulting to id:

#[derive(SqlxInsert)]
#[key(user_id)]
pub struct UserValues { /* ... */ }

Field requirements​

Every field must implement sqlx::Encode + sqlx::Type + Send. On MySQL, every field must also implement Clone — this applies to the whole derived struct unconditionally (not just when you call insert), because the upsert/upsert_all methods #[derive(SqlxInsert)] also generates on the same struct (see upsert) need to keep a copy of whichever field ends up being the runtime-selected conflict column, and that code is compiled as part of the struct's impl block regardless of whether you ever call it.

See also​