Uncompilable code generated by sea-orm-cli
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 9.9k
- Forks
- 734
- Avg merge
- 6h 36m
- Merged PRs (30d)
- 8
Description
Description
Uncompilable entities files are generated when using sea-orm-cli against Postgres, when:
- the table's primary key is multi-columned, AND
- the table itself contains SelfRef, AND
- the said table is refereneced by foreign keys from other tables.
Steps to Reproduce
- Copy this as your
main.rs
use sea_orm::sea_query::{ColumnDef, ForeignKey, Index, Table};
use sea_orm::DbErr;
use sea_orm_migration::{async_trait, MigrationName, MigrationTrait, MigratorTrait, SchemaManager};
use sea_orm_migration::{cli, sea_query};
// !! Uncomment this line after generating entities rs files at ./entities/*
// mod entities;
pub struct Migrator;
pub struct Migration;
#[async_trait::async_trait]
impl MigratorTrait for Migrator {
fn migrations() -> Vec<Box<dyn MigrationTrait>> {
vec![Box::new(Migration)]
}
}
impl MigrationName for Migration {
fn name(&self) -> &str {
"m20250101_000001_demo"
}
}
#[async_trait::async_trait]
impl MigrationTrait for Migration {
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
// Create DemoTable table
{
let mut main_table = Table::create();
let mut table = main_table.table(DemoTable::Table);
table = table.col(ColumnDef::new(DemoTable::CompKey1).uuid().not_null());
table = table.col(ColumnDef::new(DemoTable::CompKey2).uuid().not_null());
table = table.col(ColumnDef::new(DemoTable::RefCompKey1).uuid().not_null());
table = table.col(ColumnDef::new(DemoTable::RefCompKey2).uuid().not_null());
table = table.primary_key(
Index::create()
.col(DemoTable::CompKey1)
.col(DemoTable::CompKey2),
);
table = table.foreign_key(
ForeignKey::create()
.take()
.from(
DemoTable::Table,
(DemoTable::RefCompKey1, DemoTable::RefCompKey2),
)
.to(DemoTable::Table, (DemoTable::CompKey1, DemoTable::CompKey2)),
);
let _ = manager.create_table(table.to_owned()).await?;
}
// Create DemoTableForeign table
{
let mut main_table = Table::create();
let mut table = main_table.table(DemoTableForeign::Table);
table = table.col(ColumnDef::new(DemoTableForeign::Id).uuid().not_null());
table = table.col(
ColumnDef::new(DemoTableForeign::PointerKey1)
.uuid()
.not_null(),
);
table = table.col(
ColumnDef::new(DemoTableForeign::PointerKey2)
.uuid()
.not_null(),
);
table = table.primary_key(Index::create().col(DemoTableForeign::Id));
table = table.foreign_key(
ForeignKey::create()
.take()
.from(
DemoTableForeign::Table,
(DemoTableForeign::PointerKey1, DemoTableForeign::PointerKey2),
)
.to(DemoTable::Table, (DemoTable::CompKey1, DemoTable::CompKey2)),
);
let _ = manager.create_table(table.to_owned()).await?;
}
Ok(())
}
async fn down(&self, _manager: &SchemaManager) -> Result<(), DbErr> {
todo!(); // not relevant to this report
}
}
#[derive(sea_orm::Iden)]
pub enum DemoTable {
Table,
CompKey1,
CompKey2,
RefCompKey1,
RefCompKey2,
}
#[derive(sea_orm::Iden)]
pub enum DemoTableForeign {
Table,
Id,
PointerKey1,
PointerKey2,
}
#[async_std::main]
async fn main() {
cli::run_cli(Migrator).await;
}
-
Run
cargo run && sea-orm-cli generate entity -o ./src/entities/ -u postgres://U:P@localhost/TESTDB(replace the url with your test db) -
Uncomment line 7
mod entities;of the above givenmain.rs. -
The entities files
demo_table_foreign.rsanddemo_table.rsboth report a compile time error.
Expected Behavior
The generated entities files should NOT contain compile-time errors.
Actual Behavior
The generated entities files (when included in the project), fails cargo check and report compile-time errors.
error[E0599]: no variant or associated item named `DemoTable` found for enum `demo_table::Relation` in the current scope
--> src\entities\demo_table.rs:35:43
|
17 | pub enum Relation {
| ----------------- variant or associated item `DemoTable` not found for this enum
...
35 | Some(super::demo_table::Relation::DemoTable.def().rev())
| ^^^^^^^^^ variant or associated item not found in `Relation`
error[E0599]: no variant or associated item named `DemoTable` found for enum `demo_table::Relation` in the current scope
--> src\entities\demo_table_foreign.rs:28:38
|
28 | super::demo_table::Relation::DemoTable.def()
| ^^^^^^^^^ variant or associated item not found in `Relation`
|
::: src\entities\demo_table.rs:17:1
|
17 | pub enum Relation {
| ----------------- variant or associated item `DemoTable` not found for this enum
Reproduces How Often
This is always reproducible, tested on Postgres as the backend.
Workarounds
The current workaround is to manually change the line in the entity files from:
Some(super::demo_table::Relation::DemoTable.def().rev())
to
Some(super::demo_table::Relation::SelfRef.def().rev())
This has to be done manually for EACH of the problematic file.
After some testings, there seem to be no problems / incorrect behaviour when reading / writing to database after the above manual change.
Reproducible Example
The min. reproducible example is provided above.
Versions
Crate deps:
$ cargo tree | grep sea-
├── sea-orm v1.1.10
│ ├── sea-orm-macros v1.1.10 (proc-macro)
│ │ ├── sea-bae v0.2.1 (proc-macro)
│ ├── sea-query v0.32.4
│ │ ├── sea-query-derive v0.4.3 (proc-macro)
│ ├── sea-query-binder v0.7.0
│ │ ├── sea-query v0.32.4 (*)
└── sea-orm-migration v1.1.10
├── sea-orm v1.1.10 (*)
├── sea-orm-cli v1.1.10
│ ├── sea-schema v0.16.1
│ │ ├── sea-query v0.32.4 (*)
│ │ └── sea-schema-derive v0.3.0 (proc-macro)
├── sea-schema v0.16.1 (*)
Cargo.toml:
...
[dependencies]
async-std = { version = "1", features = ["attributes", "tokio1"] }
sea-orm = { version = "1.1.7", features = [
"sqlx-sqlite",
"sqlx-postgres",
"runtime-async-std-native-tls",
"macros",
"with-json",
"debug-print",
"with-uuid",
] }
sea-orm-migration = "1.1.10"
Rust edition: 2024
OS: Windows 11 23H2
Database: Postgres (running in Docker, sha256:f49abb9855df03f1829d6bd95bc8f5e9a24e1fd1bd11cab99bc2ef90f6960f6d)
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
Run the provided migration and sea-orm-cli generate entity command, then inspect the generated demo_table.rs and demo_table_foreign.rs files. Trace why the generated relation refers to DemoTable instead of SelfRef, and verify that uncommenting mod entities allows cargo check to pass without manual edits.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- postgres, rust
- Domain
- database, tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100