in entity first schema sync does not sync existing foreign key actions
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 9.9k
- Forks
- 734
- Avg merge
- 6h 36m
- Merged PRs (30d)
- 8
Description
Description
In Entity First workflow you can specify on_delete action on relations.
Schema sync will specify this action on foreign key creation.
But if foreign key already exists in database it won't change it if it was changed in schema, so if you've changed action in entity definition it won't be applied by schema sync.
Steps to Reproduce
- Setup Entity First workflow with sqlite file database
- Define two entities with relation:
mod role {
use super::role_permission;
use sea_orm::entity::prelude::*;
#[sea_orm::model]
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
#[sea_orm(table_name = "role")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: u32,
pub name: String,
#[sea_orm(has_many)]
pub permissions: HasMany<role_permission::Entity>,
}
impl ActiveModelBehavior for ActiveModel {}
}
mod role_permission {
use super::role;
use sea_orm::entity::prelude::*;
#[sea_orm::model]
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
#[sea_orm(table_name = "role_permission")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub role_id: u32,
#[sea_orm(primary_key, auto_increment = false)]
pub name: String,
#[sea_orm(belongs_to, from = "role_id", to = "id")]
pub role: HasOne<role::Entity>,
}
impl ActiveModelBehavior for ActiveModel {}
}
- Launch schema sync, so it will create database
- Add foreign key on delete action in entity definition:
#[sea_orm(belongs_to, from = "role_id", to = "id", on_delete = "Cascade")]
pub role: HasOne<role::Entity>,
- Launch schema sync, it won't change action of foreign key existing in database
- Check foreign key in database viewer
sqlite3 database.sqlite ".schema role_permission"or try to create role with permissions and then delete this role, sqlite will return error "FOREIGN KEY constraint failed" even though the foreign key action on_delete = "Cascade" is specified in entity definition:
role::ActiveModelEx {
id: Set(1u32),
name: Set("admin".into()),
permissions: sea_orm::HasManyModel::Replace(vec![
role_permission::ActiveModelEx {
name: Set("moderate".into()),
..Default::default()
},
role_permission::ActiveModelEx {
name: Set("ban".into()),
..Default::default()
},
]),
..Default::default()
}
.insert(&db)
.await
.unwrap();
role::Entity::delete_by_id(1u32).exec(&db).await.unwrap();
// Exec(SqlxError(Database(SqliteError { code: 787, message: "FOREIGN KEY constraint failed" })))
- If you delete database file and then sync schema, it will apply on delete foreign key action and delete in code snippet above will work without errors and in database schema view will appear foreign key on delete action
Expected Behavior
Schema sync should have monitored on delete action in existing foreign key, compared with schema and changed it.
Actual Behavior
Schema sync ignored foreign key on delete action change.
Reproduces How Often
Reproducible when you forgot to add foreign key on delete action.
Workarounds
Delete database file if there's no important data, so sync will create foreign key from scratch.
Or change it manually using database viewer.
Versions
sea-orm = { version = "2.0.0-rc.32", features = [
"sqlx-sqlite",
"runtime-tokio-rustls",
"macros",
"debug-print",
"schema-sync",
"entity-registry",
] }
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the schema sync path used by the Entity First workflow and its handling of existing SQLite foreign keys. Reproduce the issue by changing the relation's on_delete action after the database exists, then inspect the foreign-key comparison and update behavior. Done means schema sync applies the changed action without deleting the database, and the provided delete operation succeeds.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust, sqlite
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100