volatiletech / sqlboiler

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

Column aliases not preserved in 09_relationship_to_many_eager.go.tpl #415

Closed nwidger closed 5 years ago

nwidger commented 5 years ago

If you're having a generation problem please answer these questions before submitting your issue. Thanks!

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

SQLBoiler v3.1.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 --wipe sqlite3

If this happened at runtime what code produced the issue? (if not applicable leave blank)

The results.Scan call in the 09_relationship_to_many_eager.go.tpl used to create part of models/users.go in the generated code.

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)

using driver: /Users/niels/go/bin/sqlboiler-sqlite3
{"config":{"driver_name":"sqlite3","driver_config":{"blacklist":null,"dbname":"test.db","whitelist":null},"pkg_name":"models","out_folder":"models","debug":true,"wipe":true,"struct_tag_casing":"snake","imports":{"all":{"Standard":["\"database/sql\"","\"fmt\"","\"reflect\"","\"strings\"","\"sync\"","\"time\"","\"context\""],"ThirdParty":["\"github.com/pkg/errors\"","\"github.com/volatiletech/sqlboiler/boil\"","\"github.com/volatiletech/sqlboiler/queries\"","\"github.com/volatiletech/sqlboiler/queries/qm\"","\"github.com/volatiletech/sqlboiler/strmangle\""]},"test":{"Standard":["\"bytes\"","\"reflect\"","\"testing\"","\"context\""],"ThirdParty":["\"github.com/volatiletech/sqlboiler/boil\"","\"github.com/volatiletech/sqlboiler/queries\"","\"github.com/volatiletech/sqlboiler/randomize\"","\"github.com/volatiletech/sqlboiler/strmangle\""]},"singleton":{"boil_queries":{"Standard":null,"ThirdParty":["\"github.com/volatiletech/sqlboiler/drivers\"","\"github.com/volatiletech/sqlboiler/queries\"","\"github.com/volatiletech/sqlboiler/queries/qm\""]},"boil_types":{"Standard":["\"strconv\""],"ThirdParty":["\"github.com/pkg/errors\"","\"github.com/volatiletech/sqlboiler/boil\"","\"github.com/volatiletech/sqlboiler/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/boil\""]},"boil_queries_test":{"Standard":["\"bytes\"","\"fmt\"","\"io\"","\"io/ioutil\"","\"math/rand\"","\"regexp\""],"ThirdParty":["\"github.com/volatiletech/sqlboiler/boil\""]},"boil_suites_test":{"Standard":["\"testing\""],"ThirdParty":null},"sqlite3_main_test":{"Standard":["\"database/sql\"","\"fmt\"","\"io\"","\"math/rand\"","\"os\"","\"os/exec\"","\"path/filepath\"","\"regexp\""],"ThirdParty":["_ \"github.com/mattn/go-sqlite3\"","\"github.com/pkg/errors\"","\"github.com/spf13/viper\""]}},"based_on_type":{"null.Bool":{"Standard":[],"ThirdParty":["\"github.com/volatiletech/null\""]},"null.Bytes":{"Standard":[],"ThirdParty":["\"github.com/volatiletech/null\""]},"null.Float32":{"Standard":[],"ThirdParty":["\"github.com/volatiletech/null\""]},"null.Float64":{"Standard":[],"ThirdParty":["\"github.com/volatiletech/null\""]},"null.Int":{"Standard":[],"ThirdParty":["\"github.com/volatiletech/null\""]},"null.Int16":{"Standard":[],"ThirdParty":["\"github.com/volatiletech/null\""]},"null.Int32":{"Standard":[],"ThirdParty":["\"github.com/volatiletech/null\""]},"null.Int64":{"Standard":[],"ThirdParty":["\"github.com/volatiletech/null\""]},"null.Int8":{"Standard":[],"ThirdParty":["\"github.com/volatiletech/null\""]},"null.String":{"Standard":[],"ThirdParty":["\"github.com/volatiletech/null\""]},"null.Time":{"Standard":[],"ThirdParty":["\"github.com/volatiletech/null\""]},"null.Uint":{"Standard":[],"ThirdParty":["\"github.com/volatiletech/null\""]},"null.Uint16":{"Standard":[],"ThirdParty":["\"github.com/volatiletech/null\""]},"null.Uint32":{"Standard":[],"ThirdParty":["\"github.com/volatiletech/null\""]},"null.Uint64":{"Standard":[],"ThirdParty":["\"github.com/volatiletech/null\""]},"null.Uint8":{"Standard":[],"ThirdParty":["\"github.com/volatiletech/null\""]},"time.Time":{"Standard":["\"time\""],"ThirdParty":[]},"types.Decimal":{"Standard":[],"ThirdParty":["\"github.com/volatiletech/sqlboiler/types\""]},"types.NullDecimal":{"Standard":[],"ThirdParty":["\"github.com/volatiletech/sqlboiler/types\""]}}},"aliases":{"tables":{"user_videos":{"relationships":{"FK_0":{"local":"Users","foreign":"Videos"},"FK_1":{"local":"Videos","foreign":"Users"}}},"users":{"up_plural":"Users","up_singular":"User","down_plural":"users","down_singular":"user","columns":{"id":"ID","name":"Name"}},"videos":{"up_plural":"Videos","up_singular":"Video","down_plural":"videos","down_singular":"video","columns":{"deleted":"Deleted","id":"ID","name":"Name","sha256sum":"SHA256Sum"}}}}},"driver_config":{"blacklist":null,"dbname":"test.db","whitelist":null},"schema":"","dialect":{"lq":34,"rq":34,"use_index_placeholders":false,"use_last_insert_id":true,"use_schema":false,"use_default_keyword":false,"use_auto_columns":false,"use_top_clause":false,"use_output_clause":false,"use_case_when_exists_clause":false},"tables":[{"name":"user_videos","schema_name":"","columns":[{"name":"user_id","type":"int64","db_type":"INT","default":"","nullable":false,"unique":true,"validated":false,"arr_type":null,"udt_name":"","full_db_type":"INT","auto_generated":false},{"name":"video_id","type":"int64","db_type":"INT","default":"","nullable":false,"unique":true,"validated":false,"arr_type":null,"udt_name":"","full_db_type":"INT","auto_generated":false}],"p_key":{"name":"","columns":["user_id","video_id"]},"f_keys":[{"table":"user_videos","name":"FK_0","column":"video_id","nullable":false,"unique":true,"foreign_table":"videos","foreign_column":"id","foreign_column_nullable":false,"foreign_column_unique":true},{"table":"user_videos","name":"FK_1","column":"user_id","nullable":false,"unique":true,"foreign_table":"users","foreign_column":"id","foreign_column_nullable":false,"foreign_column_unique":true}],"is_join_table":true,"to_one_relationships":null,"to_many_relationships":null},{"name":"users","schema_name":"","columns":[{"name":"id","type":"int64","db_type":"INT","default":"","nullable":false,"unique":true,"validated":false,"arr_type":null,"udt_name":"","full_db_type":"INT","auto_generated":false},{"name":"name","type":"string","db_type":"TEXT","default":"","nullable":false,"unique":false,"validated":false,"arr_type":null,"udt_name":"","full_db_type":"TEXT","auto_generated":false}],"p_key":{"name":"","columns":["id"]},"f_keys":null,"is_join_table":false,"to_one_relationships":null,"to_many_relationships":[{"name":"","table":"users","column":"id","nullable":false,"unique":true,"foreign_table":"videos","foreign_column":"id","foreign_column_nullable":false,"foreign_column_unique":true,"to_join_table":true,"join_table":"user_videos","join_local_fkey_name":"FK_1","join_local_column":"user_id","join_local_column_nullable":false,"join_local_column_unique":true,"join_foreign_fkey_name":"FK_0","join_foreign_column":"video_id","join_foreign_column_nullable":false,"join_foreign_column_unique":true}]},{"name":"videos","schema_name":"","columns":[{"name":"id","type":"int64","db_type":"INT","default":"","nullable":false,"unique":true,"validated":false,"arr_type":null,"udt_name":"","full_db_type":"INT","auto_generated":false},{"name":"name","type":"string","db_type":"TEXT","default":"","nullable":false,"unique":false,"validated":false,"arr_type":null,"udt_name":"","full_db_type":"TEXT","auto_generated":false},{"name":"deleted","type":"string","db_type":"BOOL","default":"false","nullable":false,"unique":false,"validated":false,"arr_type":null,"udt_name":"","full_db_type":"BOOL","auto_generated":false},{"name":"sha256sum","type":"string","db_type":"TEXT","default":"","nullable":false,"unique":false,"validated":false,"arr_type":null,"udt_name":"","full_db_type":"TEXT","auto_generated":false}],"p_key":{"name":"","columns":["id"]},"f_keys":null,"is_join_table":false,"to_one_relationships":null,"to_many_relationships":[{"name":"","table":"videos","column":"id","nullable":false,"unique":true,"foreign_table":"users","foreign_column":"id","foreign_column_nullable":false,"foreign_column_unique":true,"to_join_table":true,"join_table":"user_videos","join_local_fkey_name":"FK_0","join_local_column":"video_id","join_local_column_nullable":false,"join_local_column_unique":true,"join_foreign_fkey_name":"FK_1","join_foreign_column":"user_id","join_foreign_column_nullable":false,"join_foreign_column_unique":true}]}],"templates":[{"name":"templates/00_struct.go.tpl","loader":"asset:templates/00_struct.go.tpl"},{"name":"templates/01_types.go.tpl","loader":"asset:templates/01_types.go.tpl"},{"name":"templates/02_hooks.go.tpl","loader":"asset:templates/02_hooks.go.tpl"},{"name":"templates/03_finishers.go.tpl","loader":"asset:templates/03_finishers.go.tpl"},{"name":"templates/04_relationship_to_one.go.tpl","loader":"asset:templates/04_relationship_to_one.go.tpl"},{"name":"templates/05_relationship_one_to_one.go.tpl","loader":"asset:templates/05_relationship_one_to_one.go.tpl"},{"name":"templates/06_relationship_to_many.go.tpl","loader":"asset:templates/06_relationship_to_many.go.tpl"},{"name":"templates/07_relationship_to_one_eager.go.tpl","loader":"asset:templates/07_relationship_to_one_eager.go.tpl"},{"name":"templates/08_relationship_one_to_one_eager.go.tpl","loader":"asset:templates/08_relationship_one_to_one_eager.go.tpl"},{"name":"templates/09_relationship_to_many_eager.go.tpl","loader":"asset:templates/09_relationship_to_many_eager.go.tpl"},{"name":"templates/10_relationship_to_one_setops.go.tpl","loader":"asset:templates/10_relationship_to_one_setops.go.tpl"},{"name":"templates/11_relationship_one_to_one_setops.go.tpl","loader":"asset:templates/11_relationship_one_to_one_setops.go.tpl"},{"name":"templates/12_relationship_to_many_setops.go.tpl","loader":"asset:templates/12_relationship_to_many_setops.go.tpl"},{"name":"templates/13_all.go.tpl","loader":"asset:templates/13_all.go.tpl"},{"name":"templates/14_find.go.tpl","loader":"asset:templates/14_find.go.tpl"},{"name":"templates/15_insert.go.tpl","loader":"asset:templates/15_insert.go.tpl"},{"name":"templates/16_update.go.tpl","loader":"asset:templates/16_update.go.tpl"},{"name":"templates/18_delete.go.tpl","loader":"asset:templates/18_delete.go.tpl"},{"name":"templates/19_reload.go.tpl","loader":"asset:templates/19_reload.go.tpl"},{"name":"templates/20_exists.go.tpl","loader":"asset:templates/20_exists.go.tpl"},{"name":"templates/21_auto_timestamps.go.tpl","loader":"asset:templates/21_auto_timestamps.go.tpl"},{"name":"templates/singleton/boil_queries.go.tpl","loader":"asset:templates/singleton/boil_queries.go.tpl"},{"name":"templates/singleton/boil_table_names.go.tpl","loader":"asset:templates/singleton/boil_table_names.go.tpl"},{"name":"templates/singleton/boil_types.go.tpl","loader":"asset:templates/singleton/boil_types.go.tpl"},{"name":"templates_test/00_types.go.tpl","loader":"asset:templates_test/00_types.go.tpl"},{"name":"templates_test/all.go.tpl","loader":"asset:templates_test/all.go.tpl"},{"name":"templates_test/delete.go.tpl","loader":"asset:templates_test/delete.go.tpl"},{"name":"templates_test/exists.go.tpl","loader":"asset:templates_test/exists.go.tpl"},{"name":"templates_test/find.go.tpl","loader":"asset:templates_test/find.go.tpl"},{"name":"templates_test/finishers.go.tpl","loader":"asset:templates_test/finishers.go.tpl"},{"name":"templates_test/hooks.go.tpl","loader":"asset:templates_test/hooks.go.tpl"},{"name":"templates_test/insert.go.tpl","loader":"asset:templates_test/insert.go.tpl"},{"name":"templates_test/relationship_one_to_one.go.tpl","loader":"asset:templates_test/relationship_one_to_one.go.tpl"},{"name":"templates_test/relationship_one_to_one_setops.go.tpl","loader":"asset:templates_test/relationship_one_to_one_setops.go.tpl"},{"name":"templates_test/relationship_to_many.go.tpl","loader":"asset:templates_test/relationship_to_many.go.tpl"},{"name":"templates_test/relationship_to_many_setops.go.tpl","loader":"asset:templates_test/relationship_to_many_setops.go.tpl"},{"name":"templates_test/relationship_to_one.go.tpl","loader":"asset:templates_test/relationship_to_one.go.tpl"},{"name":"templates_test/relationship_to_one_setops.go.tpl","loader":"asset:templates_test/relationship_to_one_setops.go.tpl"},{"name":"templates_test/reload.go.tpl","loader":"asset:templates_test/reload.go.tpl"},{"name":"templates_test/select.go.tpl","loader":"asset:templates_test/select.go.tpl"},{"name":"templates_test/singleton/boil_main_test.go.tpl","loader":"asset:templates_test/singleton/boil_main_test.go.tpl"},{"name":"templates_test/singleton/boil_queries_test.go.tpl","loader":"asset:templates_test/singleton/boil_queries_test.go.tpl"},{"name":"templates_test/singleton/boil_suites_test.go.tpl","loader":"asset:templates_test/singleton/boil_suites_test.go.tpl"},{"name":"templates_test/singleton/sqlite3_main_test.go.tpl","loader":"base64:(sha256 of content): 78996d40b2cc529f557aaa4cf9be0e0ef498bf1cdb1d83df45c40c6236bed753"},{"name":"templates_test/types.go.tpl","loader":"asset:templates_test/types.go.tpl"},{"name":"templates_test/update.go.tpl","loader":"asset:templates_test/update.go.tpl"}]}

Please provide a relevant database schema so we can replicate your issue (Provided you are comfortable sharing this)

create table users (
    id int not null primary key,
    name text not null
);

create table videos (
    id int not null primary key,
    name text not null,
    deleted bool not null default false,
    sha256sum text not null
);

create table user_videos (
    user_id int not null,
    video_id int not null,

    primary key (user_id, video_id),
    foreign key (user_id) references users (id),
    foreign key (video_id) references videos (id)
);

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

In my sqlboiler configuration file, I created a column alias for the sha256sum column of the videos table so that the generated Video struct in models/videos.go had a field named SHA256Sum instead of Sha256sum, in accordance with Go naming conventions:

[sqlite3]
dbname = "test.db"

[aliases.tables.videos.columns]
sha256sum = "SHA256Sum"

Unfortunately, the generated userL.LoadVideos method in models/users.go doesn't seem to respect the column alias, and refers to Sha256sum in a Scan causing a compile-time error:

        err = results.Scan(&one.ID, &one.Name, &one.Deleted, &one.Sha256sum, &localJoinCol)

I believe the generated code comes from the template 09_relationship_to_many_eager.go.tpl, but I'm not sure how to fix the issue.

nwidger commented 5 years ago

The alias is also not preserved in the videoDBTypes global in models/videos_test.go:

    videoDBTypes = map[string]string{`Deleted`: `BOOL`, `ID`: `INT`, `Name`: `TEXT`, `Sha256sum`: `TEXT`}

Please let me know if I can provide any further info to help track down this bug!

nwidger commented 5 years ago

I found some time and tried to take a stab at fixing the issue myself in PR #416.

aarondl commented 5 years ago

Hey @nwidger. Thanks so much for the PR! I did end up not accepting it the way it was simply because of the breaking change to an exported function. You'll see the way I fixed it is much more ugly than what you did haha. Rather than do the back and forth of shaping the PR I did the change because there was another gentleman who hit this in #411 that needed it fixed too. I credited you in the changelog for the suggested fix. Thanks again :)

nwidger commented 5 years ago

No worries, I figured my approach may have required some tweaking post-review. I'm just glad the issue is fixed. Thanks!