sea-orm icon indicating copy to clipboard operation
sea-orm copied to clipboard

Ident is not allowed to be empty; use Option<Ident> when generate entity

Open averichev opened this issue 3 years ago • 5 comments

I use command sea-orm-cli generate entity -o entity/src/ --with-serde -t host_site

Adapter is SQLite

My host_site table DDL:

create table host_site
(
    host_id integer not null
        references host,
    site_id integer not null
        references site
);

create unique index host_site_host_id_site_id_uindex
    on host_site (host_id, site_id);

And I have error: thread 'main' panicked at 'Ident is not allowed to be empty; use Option<Ident>', /Users/averichev/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-1.0.36/src/fallback.rs:686:9 note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

Need help, please

averichev avatar Apr 01 '22 19:04 averichev

After trying to pinpoint the issue I've taken notice in this line

https://github.com/SeaQL/sea-orm/blob/6a22207944d6a99ed0de8031851b4cdda7c956e9/sea-orm-codegen/src/entity/transformer.rs#L89

where after inserting

println!("{:?}", tbl_fk);
let rel: Relation = tbl_fk.into();
println!("{:?}", rel);
return rel;

and running the code we see

tbl_fk.ref_col: Vec<DynIden> = []

becomes a

rel.ref_col: Vec<String> =  [""]

I think tbl_fk.ref_col may contain a DynIden with an empty formatting in its Debug implementation (might be intended behaviour though?). I say this since from what I saw it doesn't make sense for an empty tbl_fk.ref_col to result into a non-empty vector.

If someone wants to continue looking into it feel free.

wmrmrx avatar Apr 03 '22 02:04 wmrmrx

Thank you for your investigation @wnmrmr

tyt2y3 avatar Apr 03 '22 05:04 tyt2y3

Seems like sea_schema::sqlite::TableDef::get_foreign_keys() makes the query pragma foreign_key_list(host_site) which gives

0|0|site|site_id||NO ACTION|NO ACTION|NONE
1|0|host|host_id||NO ACTION|NO ACTION|NONE

so the to column is empty. I don't know enough to do something about this.

wmrmrx avatar Apr 03 '22 13:04 wmrmrx

I just encountered this myself. When the error occurred only after creating a table with a single column FK, my initial hunch proved correct.

This DDL code will create a table and provoke the "Ident is not allowed to be empty" error, it was initially generated by my IDE, IntelliJ IDEA:

CREATE TABLE app_config (
    cfg_app     TEXT NOT NULL
        CONSTRAINT app_config_apps_app_name_fk
            REFERENCES apps
            ON UPDATE CASCADE ON DELETE CASCADE
            DEFERRABLE INITIALLY DEFERRED,
    cfg_name    TEXT NOT NULL,
    cfg_content TEXT NOT NULL,
    CONSTRAINT app_config_app_name_pk
        PRIMARY KEY (cfg_app, cfg_name)
);

This DDL will create an identical table but will not provoke the error, I modified it after another table with a compound FK:

CREATE TABLE app_config (
    cfg_app     TEXT NOT NULL,
    cfg_name    TEXT NOT NULL,
    cfg_content TEXT NOT NULL,
    CONSTRAINT app_config_app_name_pk
        PRIMARY KEY (cfg_app, cfg_name),
    CONSTRAINT app_config_apps_app_name_fk
        FOREIGN KEY (cfg_app) REFERENCES apps(app_name)
            ON UPDATE CASCADE ON DELETE RESTRICT
            DEFERRABLE INITIALLY DEFERRED
);

moschroe avatar Apr 09 '22 23:04 moschroe

Thank you everyone

REFERENCES apps # wont work
REFERENCES apps(app_name) # works

So I can confirm that the culprit is the shorthand syntax of SQLite https://www.sqlite.org/foreignkeys.html Section 3

The block above uses a shorthand form to create the foreign key constraint. Attaching a "REFERENCES <parent-table>" clause to a column definition creates a foreign key constraint that maps the column to the primary key of <parent-table>

This behaviour is not supported yet in sea-schema, so please specify the target column explicitly for now.

The ideal fix would be to handle this specifically in SQLite's schema discovery and probe the table's primary key when the to column is null.

tyt2y3 avatar Apr 10 '22 06:04 tyt2y3