+
Skip to content

Conversation

kayandra
Copy link

PR Info

  • Dependencies:
    • N/A
  • Dependents:
    • N/A

New Features

  • Cross-schema dependency discovery: When generating entities for a Postgre schema, the CLI now automatically discovers and includes tables, enums, and other types from related schemas

Bug Fixes

  • Fixed entity generation failure with cross-schema type references: Previously, running sea-orm-cli generate entity --database-schema custom_schema would fail with "type does not exist" errors when tables in custom_schema referenced enums or had foreign keys to tables in other schemas (e.g., public).

    Root cause: sea-schema's discovery was limited to the target schema only, so it couldn't resolve cross-schema type references. This was fixed by first loading all schema types/enums etc before proceeding with generation.

Breaking Changes

  • No breaking changes - the fix is backward compatible and uses the existing CLI interface

Changes

  • Updated sea-orm-cli/src/commands/generate.rs:
    • Added search_path configuration to include "$user" and public schemas
    • Preloaded the relevant types and schemas beofre generating

Testing

Manual testing performed with the reproduction case from #2584:

-- Create enum type in public schema
CREATE TYPE public.status_type AS ENUM ('active', 'inactive', 'pending');

-- Create custom schema
CREATE SCHEMA custom_schema;

-- Create table in custom schema that uses the enum from public schema
CREATE TABLE custom_schema.items (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    status public.status_type NOT NULL
);

Before:
sea-orm-cli generate entity --database-schema custom_schema
error returned from database: type "status_type" does not exist

After:
sea-orm-cli generate entity --database-schema custom_schema
Analyzing cross-schema dependencies ...
Will discover schemas: {"custom_schema", "public"}
Discovering tables in schema: custom_schema
Discovering tables in schema: public
Discovered 1 tables across 2 schemas
... Done.

Generated entity correctly includes the cross-schema enum with proper schema annotation.

"#;

let enum_rows = sqlx::query(enum_query).fetch_all(&pool).await?;
let mut all_enums: HashMap<String, Vec<String>> = HashMap::new();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this variable used for?

println!(
"Discovered {} tables across {} schemas",
all_tables.len(),
schemas_to_discover.len()
Copy link
Member

@Huliiiiii Huliiiiii Oct 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May I ask, are you doing vibe coding? This code is hard to understand and print too much logs.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used Claude to clean up when I was done

// This allows types (like enums) defined in any schema to be discovered
// PostgreSQL will search in order: target schema, then "$user", then public
// See: https://www.postgresql.org/docs/current/ddl-schemas.html#DDL-SCHEMAS-PATH
let sql = format!("SET search_path = '{schema}', \"$user\", public");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this addresses the issue... If the referenced type comes from another schema, this would still fail. Also, there will be conflicts between tables/types with the same name from different schemas.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe my approach to testing locally is a bit naive, I tested with a custom schema and public schema and it generated the entities. I'll test again

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved the status_type to a new control_schema and it was generated under the public schema. I'll fix

schemas_to_discover.len()
);

let table_stmts = all_tables
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly, this will generate tables of all schemas.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It finds all the tables and only generates the necessary ones. For example if there's a foreign key on another schema it will bring the relation in, same enums and types in other schemas

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is your code, I didn't see you filtering out tables that are not part of the target schema.

 let mut all_tables = Vec::new();

for discover_schema in schemas_to_discover.iter() {
    println!("Discovering tables in schema: {}", discover_schema);
    let discovery = SchemaDiscovery::new(pool.clone(), discover_schema);
    let discovered = discovery.discover().await?;
    all_tables.extend(discovered.tables);
}

let table_stmts = all_tables

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sea-orm-cli generate entity fails with cross-referenced types from other schemas

2 participants

点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载