SeaQL / SeaQL/sea-orm

Insert an active model and get back the last insert id doesn't work with autoincrement

Open
#2,151 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Area:last-inserted
Dominant language
Rust
Stars
9.9k
Forks
735
Avg merge
6h 36m
Merged PRs (30d)
8

Description

Description

Insert an active model and get back the last insert id doesn't work with autoincrement id.

Steps to Reproduce

  1. Create migration and generate a model
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "fruit")]
pub struct Model {
    #[sea_orm(primary_key)]
    pub id: i32,
}
  1. Insert an active model and get back the last insert id using static method
let pear = fruit::ActiveModel {
    ..Default::default() // just only autoincremented id here
};

let res: InsertResult = Fruit::insert(pear).exec(db).await?;
Expected Behavior

It must insert and return saved id

Actual Behavior

It leads an error:

"Custom Error: Custom Error: Attribute id is NotSet"
Reproduces How Often

All the time

Workarounds

Don't use static method and use such one instead:

let pear = fruit::ActiveModel {
    ..Default::default()
};

let pear: fruit::Model = pear.insert(db).await?;

Reproducible Example

  1. Run migration:
use sea_orm_migration::prelude::*;

#[derive(DeriveMigrationName)]
pub struct Migration;

#[async_trait::async_trait]
impl MigrationTrait for Migration {
    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
        manager
            .create_table(
                Table::create()
                    .table(Fruit::Table)
                    .if_not_exists()
                    .col(
                        ColumnDef::new(Fruit::Id)
                            .integer()
                            .not_null()
                            .auto_increment()
                            .primary_key(),
                    )
                    .to_owned(),
            )
            .await
    }

    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
        manager
            .drop_table(Table::drop().table(Fruit::Table).to_owned())
            .await
    }
}

#[derive(DeriveIden)]
enum Fruit {
    Table,
    Id,
}
  1. Generate a model based on migration above

  2. Then try to insert entity using generated model:

let pear = fruit::ActiveModel {
    ..Default::default() // just only autoincremented id here
};

let res: InsertResult = Fruit::insert(pear).exec(db).await?;

Versions

0.12.14

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the static Fruit::insert(pear).exec(db) entry point and compare it with the working ActiveModel::insert(db) path. Trace how an autoincrement-only ActiveModel is handled and add a regression test for the reproduced migration and insert. Done means the static insert succeeds and returns the saved id instead of reporting Attribute id is NotSet.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
databases
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.