volatiletech / sqlboiler

Generate a Go ORM tailored to your database schema.
BSD 3-Clause "New" or "Revised" License
6.7k stars 542 forks source link

Foreign key causes "panic: interface conversion: string is not error: missing method Error" #1335

Closed glenatron closed 9 months ago

glenatron commented 9 months ago

What version of SQLBoiler are you using (sqlboiler --version)?

SQLBoiler v4.15.0

What is your database and version (eg. Postgresql 10)

postgres (PostgreSQL) 16.0

If this happened at generation time what was the full SQLBoiler command you used to generate your models? (if not applicable leave blank)

sqlboiler psql --wipe

What is the output of the command above with the -d flag added to it? (Provided you are comfortable sharing this, it contains a blueprint of your schema)

panic: could not find table name: edition_format [recovered]
        panic: interface conversion: string is not error: missing method Error

goroutine 1 [running]:
github.com/volatiletech/sqlboiler/v4/drivers/sqlboiler-psql/driver.(*PostgresDriver).Assemble.func1()
        C:/Users/example-user/go/pkg/mod/github.com/volatiletech/sqlboiler/v4@v4.15.0/drivers/sqlboiler-psql/driver/psql.go:88 +0x7e
panic({0x4f00c0?, 0xc000093b10?})
        D:/Program Files/Go/src/runtime/panic.go:914 +0x21f
github.com/volatiletech/sqlboiler/v4/drivers.GetTable(...)
        C:/Users/example-user/go/pkg/mod/github.com/volatiletech/sqlboiler/v4@v4.15.0/drivers/table.go:41
github.com/volatiletech/sqlboiler/v4/drivers.setForeignKeyConstraints(0xc0001ee390, {0xc0001ee000, 0x13, 0x0?})
        C:/Users/example-user/go/pkg/mod/github.com/volatiletech/sqlboiler/v4@v4.15.0/drivers/interface.go:362 +0x594
github.com/volatiletech/sqlboiler/v4/drivers.tables({0x5d0698, 0xc0000de360}, {0x53da8b, 0x6}, {0x0?, 0x0, 0x0}, {0x0, 0x0, 0x0}, ...)
        C:/Users/example-user/go/pkg/mod/github.com/volatiletech/sqlboiler/v4@v4.15.0/drivers/interface.go:177 +0x4e5
github.com/volatiletech/sqlboiler/v4/drivers.TablesConcurrently({0x5d0698, 0xc0000de360}, {0x53da8b, 0x6}, {0x0, 0x0, 0x0}, {0x0, 0x0, 0x0}, ...)
        C:/Users/example-user/go/pkg/mod/github.com/volatiletech/sqlboiler/v4@v4.15.0/drivers/interface.go:121 +0x85
github.com/volatiletech/sqlboiler/v4/drivers/sqlboiler-psql/driver.(*PostgresDriver).Assemble(0xc0000de360, 0xe7?)
        C:/Users/example-user/go/pkg/mod/github.com/volatiletech/sqlboiler/v4@v4.15.0/drivers/sqlboiler-psql/driver/psql.go:141 +0x88f
github.com/volatiletech/sqlboiler/v4/drivers.DriverMain({0x5cfcb0, 0xc0000de360})
        C:/Users/example-user/go/pkg/mod/github.com/volatiletech/sqlboiler/v4@v4.15.0/drivers/driver_main.go:37 +0x462
main.main()
        C:/Users/example-user/go/pkg/mod/github.com/volatiletech/sqlboiler/v4@v4.15.0/drivers/sqlboiler-psql/main.go:9 +0x29
{"config":{"driver_name":"psql","driver_config":{"add-enum-types":false,"blacklist":null,"dbname":"my-database","enum-null-prefix":"Null","foreign-keys":null,"host":"localhost","pass":"1Trowch-Tudalen_Arall!","sslmode":"disable","user":"my-database","whitelist":null},"pkg_name":"models","out_folder":"models","debug":true,"enum_null_prefix":"Null","wipe":true,"struct_tag_casing":"snake","relation_tag":"-","imports":{"all":{"Standard":["\"database/sql\"","\"fmt\"","\"reflect\"","\"strings\"","\"sync\"","\"time\""],"ThirdParty":["\"github.com/friendsofgo/errors\"","\"github.com/volatiletech/sqlboiler/v4/boil\"","\"github.com/volatiletech/sqlboiler/v4/queries\"","\"github.com/volatiletech/sqlboiler/v4/queries/qm\"","\"github.com/volatiletech/sqlboiler/v4/queries/qmhelper\"","\"github.com/volatiletech/strmangle\""]},"test":{"Standard":["\"bytes\"","\"reflect\"","\"testing\""],"ThirdParty":["\"github.com/volatiletech/sqlboiler/v4/boil\"","\"github.com/volatiletech/sqlboiler/v4/queries\"","\"github.com/volatiletech/randomize\"","\"github.com/volatiletech/strmangle\""]},"singleton":{"boil_queries":{"Standard":["\"regexp\""],"ThirdParty":["\"github.com/volatiletech/sqlboiler/v4/drivers\"","\"github.com/volatiletech/sqlboiler/v4/queries\"","\"github.com/volatiletech/sqlboiler/v4/queries/qm\""]},"boil_types":{"Standard":["\"strconv\""],"ThirdParty":["\"github.com/friendsofgo/errors\"","\"github.com/volatiletech/sqlboiler/v4/boil\"","\"github.com/volatiletech/strmangle\""]}},"test_singleton":{"boil_main_test":{"Standard":["\"database/sql\"","\"flag\"","\"fmt\"","\"math/rand\"","\"os\"","\"path/filepath\"","\"strings\"","\"testing\"","\"time\""],"ThirdParty":["\"github.com/spf13/viper\"","\"github.com/volatiletech/sqlboiler/v4/boil\""]},"boil_queries_test":{"Standard":["\"bytes\"","\"fmt\"","\"io\"","\"math/rand\"","\"regexp\""],"ThirdParty":["\"github.com/volatiletech/sqlboiler/v4/boil\""]},"boil_suites_test":{"Standard":["\"testing\""],"ThirdParty":null}}},"aliases":{},"auto_columns":{},"inflections":{"Plural":{},"PluralExact":{},"Singular":{},"SingularExact":{},"Irregular":{}},"version":"4.15.0"},"driver_config":{"add-enum-types":false,"blacklist":null,"dbname":"my-database","enum-null-prefix":"Null","foreign-keys":null,"host":"localhost","pass":"1Trowch-Tudalen_Arall!","sslmode":"disable","user":"my-database","whitelist":null},"schema":"","dialect":{"lq":0,"rq":0,"use_index_placeholders":false,"use_last_insert_id":false,"use_schema":false,"use_default_keyword":false,"use_top_clause":false,"use_output_clause":false,"use_case_when_exists_clause":false,"use_auto_columns":false},"tables":null,"templates":null}
Error: exit status 2
driver (C:\Users\ben\go\bin\sqlboiler-psql.exe) exited non-zero
github.com/volatiletech/sqlboiler/v4/drivers.execute
        C:/Users/example-user/go/pkg/mod/github.com/volatiletech/sqlboiler/v4@v4.15.0/drivers/binary_driver.go:73
github.com/volatiletech/sqlboiler/v4/drivers.binaryDriver.Assemble
        C:/Users/example-user/go/pkg/mod/github.com/volatiletech/sqlboiler/v4@v4.15.0/drivers/binary_driver.go:21
github.com/volatiletech/sqlboiler/v4/boilingcore.(*State).initDBInfo
        C:/Users/example-user/go/pkg/mod/github.com/volatiletech/sqlboiler/v4@v4.15.0/boilingcore/boilingcore.go:408
github.com/volatiletech/sqlboiler/v4/boilingcore.New
        C:/Users/example-user/go/pkg/mod/github.com/volatiletech/sqlboiler/v4@v4.15.0/boilingcore/boilingcore.go:86
main.preRun
        C:/Users/example-user/go/pkg/mod/github.com/volatiletech/sqlboiler/v4@v4.15.0/main.go:222
github.com/spf13/cobra.(*Command).execute
        C:/Users/example-user/go/pkg/mod/github.com/spf13/cobra@v1.5.0/command.go:857
github.com/spf13/cobra.(*Command).ExecuteC
        C:/Users/example-user/go/pkg/mod/github.com/spf13/cobra@v1.5.0/command.go:990
github.com/spf13/cobra.(*Command).Execute
        C:/Users/example-user/go/pkg/mod/github.com/spf13/cobra@v1.5.0/command.go:918
main.main
        C:/Users/example-user/go/pkg/mod/github.com/volatiletech/sqlboiler/v4@v4.15.0/main.go:123
runtime.main
        D:/Program Files/Go/src/runtime/proc.go:267
runtime.goexit
        D:/Program Files/Go/src/runtime/asm_amd64.s:1650
unable to fetch table data
github.com/volatiletech/sqlboiler/v4/boilingcore.(*State).initDBInfo
        C:/Users/example-user/go/pkg/mod/github.com/volatiletech/sqlboiler/v4@v4.15.0/boilingcore/boilingcore.go:410
github.com/volatiletech/sqlboiler/v4/boilingcore.New
        C:/Users/example-user/go/pkg/mod/github.com/volatiletech/sqlboiler/v4@v4.15.0/boilingcore/boilingcore.go:86
main.preRun
        C:/Users/example-user/go/pkg/mod/github.com/volatiletech/sqlboiler/v4@v4.15.0/main.go:222
github.com/spf13/cobra.(*Command).execute
        C:/Users/example-user/go/pkg/mod/github.com/spf13/cobra@v1.5.0/command.go:857
github.com/spf13/cobra.(*Command).ExecuteC
        C:/Users/example-user/go/pkg/mod/github.com/spf13/cobra@v1.5.0/command.go:990
github.com/spf13/cobra.(*Command).Execute
        C:/Users/example-user/go/pkg/mod/github.com/spf13/cobra@v1.5.0/command.go:918
main.main
        C:/Users/example-user/go/pkg/mod/github.com/volatiletech/sqlboiler/v4@v4.15.0/main.go:123
runtime.main
        D:/Program Files/Go/src/runtime/proc.go:267
runtime.goexit
        D:/Program Files/Go/src/runtime/asm_amd64.s:1650
unable to initialize tables
github.com/volatiletech/sqlboiler/v4/boilingcore.New
        C:/Users/example-user/go/pkg/mod/github.com/volatiletech/sqlboiler/v4@v4.15.0/boilingcore/boilingcore.go:88
main.preRun
        C:/Users/example-user/go/pkg/mod/github.com/volatiletech/sqlboiler/v4@v4.15.0/main.go:222
github.com/spf13/cobra.(*Command).execute
        C:/Users/example-user/go/pkg/mod/github.com/spf13/cobra@v1.5.0/command.go:857
github.com/spf13/cobra.(*Command).ExecuteC
        C:/Users/example-user/go/pkg/mod/github.com/spf13/cobra@v1.5.0/command.go:990
github.com/spf13/cobra.(*Command).Execute
        C:/Users/example-user/go/pkg/mod/github.com/spf13/cobra@v1.5.0/command.go:918
main.main
        C:/Users/example-user/go/pkg/mod/github.com/volatiletech/sqlboiler/v4@v4.15.0/main.go:123
runtime.main
        D:/Program Files/Go/src/runtime/proc.go:267
runtime.goexit
        D:/Program Files/Go/src/runtime/asm_amd64.s:1650

Further information. What did you do, what did you expect?

This is a little weird. I've been using SqlBoiler for a while on this project and it has been working perfectly.

I have an edition table which had a format field in it, so I could record the format of each edition of a created document. I realised this was bad normalisation so I created an edition_format table and replaced the format field with a format_id field that was a bigint looking up to edition_format.id and created a foreign key referencing it. When I regenerated the models I got the above message.

The cause of the problem appears to be the foreign key - when I remove that constraint it works correctly. For the time being I can leave that out (I'll probably mostly query it through views anyway) but it would be good to get to the bottom of this. I have other bigint foreign key relationships that work perfectly. I saw a previous issue where this was related to casing, but everything here seems to be consistent, which makes me wonder if the word "format" might be reserved somewhere.

Please provide a relevant database schema so we can replicate your issue

This is the part of the schema that is causing the problem:

CREATE TABLE IF NOT EXISTS public.edition
(
    id bigint NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1 ),
    date_created timestamp with time zone NOT NULL DEFAULT CURRENT_TIMESTAMP,
    region character varying(16) COLLATE pg_catalog."default",
    version bigint NOT NULL DEFAULT 1,
    published boolean NOT NULL DEFAULT false,
    available boolean NOT NULL DEFAULT false,
    deleted boolean NOT NULL DEFAULT false,
    notes text COLLATE pg_catalog."default",
    image character varying(255) COLLATE pg_catalog."default",
    document_id uuid NOT NULL,
    downloads uuid[],
    length bigint,
    length_units character varying(25) COLLATE pg_catalog."default",
    format_id bigint NOT NULL,
    CONSTRAINT edition_pkey PRIMARY KEY (id),
    CONSTRAINT fk_edition_document FOREIGN KEY (document_id)
        REFERENCES public.document (id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION,
    CONSTRAINT fk_edition_format_id FOREIGN KEY (format_id)
        REFERENCES public.edition_format (id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
}

CREATE INDEX IF NOT EXISTS fki_fk_edition_document
    ON public.edition USING btree
    (document_id ASC NULLS LAST)
    TABLESPACE pg_default;

CREATE INDEX IF NOT EXISTS fki_fk_edition_format
    ON public.edition USING btree
    (format_id ASC NULLS LAST)
    TABLESPACE pg_default;

CREATE TABLE IF NOT EXISTS public.edition_format
(
    id bigint NOT NULL,
    name character varying(40) COLLATE pg_catalog."default" NOT NULL,
    CONSTRAINT format_pkey PRIMARY KEY (id)
)
glenatron commented 9 months ago

NEVER MIND! I'm a massive dork who forgot to give the new edition_format table the correct permissions for the user to read it.