Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support SQLite foreign key short hand syntax #101

Open
averichev opened this issue Apr 1, 2022 · 5 comments
Open

Support SQLite foreign key short hand syntax #101

averichev opened this issue Apr 1, 2022 · 5 comments

Comments

@averichev
Copy link

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', /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

@wmrmrx
Copy link

wmrmrx commented Apr 3, 2022

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.

@tyt2y3
Copy link
Member

tyt2y3 commented Apr 3, 2022

Thank you for your investigation @wnmrmr

@wmrmrx
Copy link

wmrmrx commented Apr 3, 2022

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.

@moschroe
Copy link

moschroe commented Apr 9, 2022

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
);

@tyt2y3
Copy link
Member

tyt2y3 commented Apr 10, 2022

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 tyt2y3 transferred this issue from SeaQL/sea-orm Feb 21, 2023
@tyt2y3 tyt2y3 changed the title Ident is not allowed to be empty; use Option<Ident> when generate entity Support SQLite foreign key short hand syntax Feb 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Triage
Development

No branches or pull requests

4 participants