You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When creating SeaORM migrations using a Sqlite database, the SchemaManager.create_foreign_key(...) and SchemaManager.drop_foreign_key(...) functions cause an error: Sqlite does not support modification of foreign key constraints to existing tables. The solution is to recreate the table with the foreign keys, but this requires multiple calls to rename the table, create a new table, copy the data over, then delete the old table.
My suggestion is to allow for the original foreign key functions to handle this under the hood, to achieve parity between Sqlite and other databases.
Here is a code example to illustrate what I'm talking about, which adds a foreign key constraint linking the existing childs table to the existing parents table (using SeaORM version 1.0.0):
use sea_orm_migration::prelude::*;use sea_orm_migration::sea_orm::DeriveIden;#[derive(DeriveIden)]pubenumParents{Table,Id,}#[derive(DeriveIden)]pubenumChilds{Table,Id,ParentId,}#[derive(DeriveIden)]#[sea_orm(iden = "old_childs_id")]pubenumOldTooltipSlugs{Table,}#[derive(DeriveMigrationName)]pubstructMigration;#[async_trait::async_trait]implMigrationTraitforMigration{asyncfnup(&self,manager:&SchemaManager) -> Result<(),DbErr>{// Ideal method, but does not work with Sqlite:// manager// .create_foreign_key(// ForeignKey::create()// .name("fk_childs_parent_id")// .from(Childs::Table, Childs::ParentId)// .to(Parents::Table, Parents::Id)// .to_owned(),// )// .await// Unideal method, but works with Sqlite:// Rename table to old table.
manager
.rename_table(Table::rename().table(Childs::Table,OldChilds::Table).to_owned(),).await?;// Create new table with foreign key this time.
manager
.create_table(Table::create().table(Childs::Table).if_not_exists().col(ColumnDef::new(Childs::Id).int().not_null().primary_key()).col(ColumnDef::new(Childs::ParentId).string().not_null()).foreign_key(ForeignKey::create().name("fk_childs_parent_id").from(Childs::Table,Childs::ParentId).to(Parents::Table,Parents::Id).on_delete(ForeignKeyAction::Cascade),).to_owned(),).await?;// Copy data over.
manager
.exec_stmt(Query::insert().into_table(Childs::Table).columns([Childs::Id,Childs::ParentId]).values_panic([/* SELECT * FROM old_childs */]).to_owned(),).await?;// Delete old table.
manager
.drop_table(Table::drop().table(OldChilds::Table).to_owned()).await}asyncfndown(&self,manager:&SchemaManager) -> Result<(),DbErr>{// Ideal method, but does not work with Sqlite:// manager// .drop_foreign_key(// ForeignKey::drop()// .name("fk_childs_parent_id")// .to_owned(),// )// .await// Unideal method, but works with Sqlite:// Rename table to old table.
manager
.rename_table(Table::rename().table(Childs::Table,OldChilds::Table).to_owned(),).await?;// Create new table without foreign key again.
manager
.create_table(Table::create().table(Childs::Table).if_not_exists().col(ColumnDef::new(Childs::Id).int().not_null().primary_key()).col(ColumnDef::new(Childs::ParentId).string().not_null()).to_owned(),).await?;// Copy data back over.
manager
.exec_stmt(Query::insert().into_table(Childs::Table).columns([Childs::Id,Childs::ParentId]).values_panic([/* SELECT * FROM old_childs */]).to_owned(),).await?;// Delete old table.
manager
.drop_table(Table::drop().table(OldChilds::Table).to_owned()).await}}
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
When creating SeaORM migrations using a Sqlite database, the
SchemaManager.create_foreign_key(...)
andSchemaManager.drop_foreign_key(...)
functions cause an error:Sqlite does not support modification of foreign key constraints to existing tables
. The solution is to recreate the table with the foreign keys, but this requires multiple calls to rename the table, create a new table, copy the data over, then delete the old table.My suggestion is to allow for the original foreign key functions to handle this under the hood, to achieve parity between Sqlite and other databases.
Here is a code example to illustrate what I'm talking about, which adds a foreign key constraint linking the existing childs table to the existing parents table (using SeaORM version 1.0.0):
Beta Was this translation helpful? Give feedback.
All reactions