Description
Description
When I use class table inheritance, sea-orm generates a has_many
relation from Parent to Child instead of has_one
. This issue is somewhat similar to #1393, but my foreign key is also a primary key and this issue happens with both PostgreSQL and SQLite. PostgreSQL is used by the actual codebase where I first encountered this, and I chose SQLite for the reproducer to make it more simple and portable.
Steps to Reproduce
- Set up a dummy sea-orm project with migrations and with SQLite driver enabled.
- Paste the migration code from the Reproducible Example section.
- Generate entities:
touch db.sqlite3 DATABASE_URL="sqlite://./db.sqlite3" sea-orm-cli migrate fresh sea-orm-cli generate entity -u "sqlite://./db.sqlite3" -o src/entities
- Open
src/entities/parent.rs
Expected Behavior
I expected to see has_one
instead of has_many
.
Actual Behavior
// In generated src/entities/parent.rs
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(has_many = "super::child::Entity")]
Child,
}
Reproduces How Often
Always.
Workarounds
In the actual codebase with PostgreSQL and different migration code, if I turn the Child's .primary_key()
into a .unique_key()
, has_one
is generated as expected. However, the Child entity doesn't compile afterwards because it must have a primary key. In the reproducer migration with SQLite this doesn't happen (it still generates has_many
). I didn't investigate the reason yet. Ping me if this is important.
Reproducible Example
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(Parent::Table)
.if_not_exists()
.col(
ColumnDef::new(Parent::Id)
.integer()
.not_null()
.auto_increment()
.primary_key(),
)
.to_owned(),
)
.await?;
manager
.create_table(
Table::create()
.table(Child::Table)
.if_not_exists()
.col(ColumnDef::new(Child::Id).integer().not_null().primary_key())
.foreign_key(
ForeignKey::create()
.from(Child::Table, Child::Id)
.to(Parent::Table, Parent::Id),
)
.to_owned(),
)
.await
}
async fn down(&self, _: &SchemaManager) -> Result<(), DbErr> {
unimplemented!();
}
}
#[derive(DeriveIden)]
pub enum Parent {
Table,
Id,
}
#[derive(DeriveIden)]
pub enum Child {
Table,
Id,
}
Versions
Linux 6.2.0-33-generic
PostgreSQL 16
SQLite 3.40.1
cargo tree | grep sea-
in the actual project with PostrgeSQL:
├── sea-orm-migration v0.12.2
│ ├── sea-orm v0.12.2
│ │ ├── sea-orm-macros v0.12.2 (proc-macro)
│ │ │ ├── sea-bae v0.2.0 (proc-macro)
│ │ ├── sea-query v0.30.0
│ │ │ ├── sea-query-derive v0.4.0 (proc-macro)
│ │ ├── sea-query-binder v0.5.0
│ │ │ ├── sea-query v0.30.0 (*)
│ ├── sea-orm-cli v0.12.2
│ │ ├── sea-schema v0.14.0
│ │ │ ├── sea-query v0.30.0 (*)
│ │ │ └── sea-schema-derive v0.2.0 (proc-macro)
│ ├── sea-schema v0.14.0 (*)
├── sea-orm v0.12.2 (*)
├── sea-query v0.30.0 (*)