First some background for what I’m trying to achieve, in-case there’s a better approach, rendering my question a moot point.
I have a Go project and I’m adding functional tests. I want the tests to bring up an actual MySQL database (by connecting to a docker container already up and running from the docker compose config that runs the tests). I want the test to then create all of the tables in the database, add some test data, run the tests and then delete everything.
In Python I used SqlAlchemy and Alembic to create a database from scratch with SQL then have the code look at that database and create an ORM that reflects it completely, including indexes and relations. I could use the migrate features on this generated ORM to bring up the database in my test environment as outlined above.
In Go I’m already invested in Gorm, so I want my generated ORM to use the Gorm hints on the table fields. I can currently use Gorm Gen to generate the ORM, however it doesn’t create any of the relations. I want these relations as I believe they are necessary to use the migrate feature to create the database correctly. I also want them so I can use the pre-loading feature to populate the structs in Go.
For example, I want to generate structs like this:
type User struct {
ID uint `json:"id" gorm:"primary_key"`
Accounts []Account `json:"accounts" gorm:"many2many:user_account"`
}
type Account struct {
ID uint `json:"id" gorm:"primary_key"`
Name string `json:"name"`
}
The documentation here seems to imply that it’s possible, but it doesn’t make complete sense to me: https://gorm.io/gen/associations.html
If I use g.GenerateAllTable()
with Gen generate g
I get all of the tables generated with all of the gorm and json hints that I want above, but it doesn’t include any of the relation information. if instead I use:
accounts := g.GenerateModel("account")
users := g.GenerateModel("user", gen.FieldRelate(field.Many2Many, "Account", accounts,
&field.RelateConfig{
// RelateSlice: true,
GORMTag: field.GormTag{"foreignKey": []string{"AccountID"}, "references": []string{"ID"}},
}),
)
g.ApplyBasic(accounts, users)
I get some pretty massive classes created with a lot of boilerplate code added for various SQL operations. It includes some relation information but it looks nothing like the structs above and doesn’t include any gorm hints.
If I need to provide code as a above to explicitly define relations I can live with it, although have about fifteen tables to deal with. However, I’m trying to match what I can achieve with python, which generates the entire ORM automatically by pointing it at an existing database and getting full migration and pre-loading support included.