I Been trying to implement the GORM Orm in our Golang project but it seems that I have a slight problem.
one of the structs has a circular dependency, so now when I try to AutoMigrate for the tables creation, I get errors since GORM is trying to create the tables by order.
example proto:
message Person{
optional string name= 1;
optional Company company = 2;
}
message Company{
optional string name= 1;
optional Workers workers= 2;
}
message Workers {
optional string name= 1;
optional Person person= 2;
}
this is a simplyfied example but is exactly how my circular dependency is. When I generate the proto using the gorm plugin, it generates the models with all the gorm annotations including the foregin keys. and then ofcourse it breaks when I try to autoMigrate them all.
the only way I found to solve this is:
- remove the Workers field from Company.
- generate the gorm models.
- run autoMigrate.
- refactor the proto file and return the Workers field back to Company.
- run autoMigrate.
- we have all tables with the appropriate FK's.
I tried searching online for any ideas but cannot seem to find any.
Any help/ideas are appriciated!
I was able to achieve what you need by following this approach. Unfortunately, I'm not too familiar with
protomessages so I share only the relative Go code you should use. If I'm not wrong the association you defined in theprotomessage is translated intobelongsTowithinGORM. Otherwise, you should have used therepeatedkeyword (am I right?).After the premise, I'm gonna share the code and, then, the explanation.
Alright, let me walk you through the relevant sections.
The structs definition
Here, you must forecast that every association could be
NULL. That's why I used pointers to define all of them. Thanks to this, you can create a circular dependency like this:Plus, I overrode the table name for the struct
Personby settingpeople. Probably,GORMis smart enough to do this by itself but never tried it.SQL objects definition
When you instantiate a
gormclient, you've to be sure that the Foreign Keys don't get created when you migrate. To achieve this, you've to set the fieldDisableForeignKeyConstraintWhenMigratingtotruein thegorm.Configstruct. Thanks to this, the foreign keys creation is up to you. The latter is done through theCreateConstraintmethod in which you specify:Lastly, you can notice that I run the
AutoMigratemethod to create the tables without the foreign keys.The writing logic
Due to the layout of the tables, the
INSERTlogic must be divided into two parts. In the first one, you insert the records in their own table (e.g.Personinto thepeopletable,Companyintocompanies, and so on). We have deliberately left the foreign keys toNULL, otherwise we got an error. The first will always raise an error if the related record hasn't been inserted yet.Then, we set each foreign key to the right value by using the
Updatemethod.Final thoughts
I left in the code some commented statements to prove that if you try to assign some not-existent value as the foreign key, it breaks. That means you're allowed to either insert
NULLor a right value in these columns.I used this package
"github.com/samber/lo"to easily get a pointer value starting from a literal (e.g.1).Let me know if this helps solve your issue, thanks!