I have these 2 models with many-to-many relationship:
type Person struct {
tableName struct{} `sql:"person"`
UUID string `sql:"person_uuid,pk"`
ContactDatas []ContactData `pg:",many2many:person_contact_data,joinFK:"`
}
type ContactData struct {
tableName struct{} `sql:"contact_data"`
UUID string `sql:"contact_data_uuid,pk"`
}
And model for person_contact_data table is:
type PersonContactData struct {
tableName struct{} `sql:"person_contact_data"`
PersonUUID string `sql:"person_uuid"`
ContactDataUUID string `sql:"contact_data_uuid"`
}
If joinFK in ContactDatas struct tag is empty go-pg adds underscore under the hood, so generated SQL part looks like this: WHERE ("contact_data"."contact_data_uuid" = person_contact_data."_contact_data_uuid").
Is there a way to specify joining keys completely manual?
I was using version 5. In latest version this was fixed, now you can specify full joining keys:
type Person struct {
tableName struct{} `sql:"person"`
UUID string `sql:"person_uuid,pk"`
ContactDatas []ContactData `pg:",many2many:person_contact_data,fk:person_uuid,joinFK:contact_data_uuid"`
}
Related
import "gorm.io/gorm"
type Object struct {
gorm.Model
ObjectId string `gorm:"primary_key"`
ListItems []ListItem `gorm:"foreignKey:ObjectId;references:ObjectId"`
}
type ListItem struct {
gorm.Model
ObjectId string
Data string
}
I define two objects, then try to auto migrate following the guide
db.Migrator().CreateConstraint(&Object{}, "ListItems")
db.Migrator().CreateConstraint(&Object{}, "fk_object_list_items")
db.AutoMigrate(&Object{}, &ListItem{})
Fails with
ERROR: there is no unique constraint matching given keys for referenced table "blobber_ch
I can't find any examples for this. I tried different permutations of everything.
I suspect the foreign key in the migration does not match the foreign key in the model.
You have two primary_key for Object struct as gorm.Model already have one:
ID uint `gorm:"primarykey"`
You have two otpions : not to use gorm.Model or get rid of ObjectId primary_key and clean references:ObjectId from gorm annotation.
type Object struct {
gorm.Model
ObjectId string
ListItems []ListItem `gorm:"foreignKey:ObjectId;"`
}
type ListItem struct {
gorm.Model
ObjectId string
Data string
}
db.Migrator().CreateConstraint(&Object{}, "ListItems")
db.Migrator().CreateConstraint(&Object{}, "fk_object_list_items")
db.AutoMigrate(&Object{}, &ListItem{})
I have a set of employees defined in a JSON-file:
type PrimitiveEmployee struct {
PrimitiveID string `xml:"ID,attr"`
ContractID []string `xml:"ContractID"`
}
Both ID and ContractID is letters, but they are not necessarily given continuous sequence of letters. For instance, there might exist an employee with PrimitiveID=A and another with PrimitiveID=C, but not an employee with PrimitiveID=B.
I want to convert this data into:
type Employee struct {
ID int
PrimitiveID string
Contracts []Contract
}
The thing is, I want the the employee-ID to start at 0 and increment with one for each time the struct is initialized. Sort of like a an autoincrement ID in a database or iota in a enum.
The employee with PrimitiveID=A will then automatically be created with ID=0, while the employee with PrimitiveID=C will get ID=1.
I just cant figure out how to solve this in a struct.
Greatly appreciate any help or pointers here.
Create a custom type to manage the unique incrementing ID:
type autoInc struct {
sync.Mutex // ensures autoInc is goroutine-safe
id int
}
func (a *autoInc) ID() (id int) {
a.Lock()
defer a.Unlock()
id = a.id
a.id++
return
}
So you can use it in targeted places or at the package level:
var ai autoInc // global instance
You can then create "constructor" functions to leverage this:
func NewEmployee() *Employee {
return &Employee{
ID: ai.ID(),
}
}
Marshaling JSON data to Employee can then be performed and the ID will be preserved - provided the JSON data does not container an ID tag.
https://play.golang.org/p/0iTaQSzTPZ_j
I'm planning to use GORM with an existing database, therefore I'm creating some models for it. However, I've got one problem - GORM automatically renames all column to lower snake case. I don't really need it, because the database I work with doesn't really use such names. I've found out, that I can use tag
`gorm:"column_name:`
In order to prevent my columns from being renamed. However, it doesn't really seem to be a viable solution for me, because I have a bunch of models with tons of columns. Is there any way to switch off this "renaming" policy from GORM, or to automatically add a tag to all of my models?
My models look like that:
type FOOD_DES struct {
NDB_NO string `gorm:"primary_key"`
FdGrp_Cd FD_GROUP
Long_Desc string
Shrt_Desc string
ComName string
ManufacName string
Survey string
Ref_desc string
Refuse float32
SciName string
N_Factor float32
Pro_Factor float32
Fat_Factor float32
CHO_Factor float32
}
From doc:
GORM allows users to change the naming conventions by overriding the
default NamingStrategy which need to implements interface Namer
type Namer interface {
TableName(table string) string
ColumnName(table, column string) string
JoinTableName(table string) string
RelationshipFKName(Relationship) string
CheckerName(table, column string) string
IndexName(table, column string) string
}
So just implement interface Namer.
And in the old version, you can do like (Ref)
gorm.AddNamingStrategy(&gorm.NamingStrategy{
DB: func(name string) string {
return name
},
Table: func(name string) string {
return name
},
Column: func(name string) string {
return name
},
})
I'm trying to create a self-reference in a (my)sql table using golang gorm. At the moment my code looks like this:
type Person struct {
gorm.Model
Name string
Children []*Person `gorm:"ForeignKey:ParentID"`
ParentID uint
}
func main() {
/* code to get database connection omitted */
p := &Person{Name:"Sally"}
db.Create(p)
children := []*Person{ {Name:"Jane", ParentID:p.ID},
{Name:"Tom", ParentID:p.ID}}
for _, child := range children {
db.Create(child)
}
var children2 []*Person
db.Model(p).Related(children2, "ParentID")
}
The code is failing with an error "reflect.Value.Set using unaddressable value".
Does anybody know how to get this relationship working using go gorm?
Many thanks in advance :)
Fortunately gorm have added lately this feature (reference: here).
In your case should be like this:
type Person struct {
gorm.Model
Name string
Children []*Person `gorm:"many2many: children;association_jointable_foreignkey:children_id"`
}
How do I define my structs to specify a multi-column unique index to Gorm in Go?
Such as:
type Something struct {
gorm.Model
First string `sql:"unique_index:unique_index_with_second"`
Second string `sql:"unique_index:unique_index_with_first"`
}
this is how you do it: You need to use the gorm struct tag and specify that the index is unique
type Something struct {
gorm.Model
First string `gorm:"index:idx_name,unique"`
Second string `gorm:"index:idx_name,unique"`
}
You can define same unique index for each column.
type Something struct {
gorm.Model
First string `sql:"unique_index:idx_first_second"`
Second string `sql:"unique_index:idx_first_second"`
}
for latest version of gorm (or for my case)
this works:
type Something struct {
gorm.Model
First string `gorm:"uniqueIndex:idx_first_second"`
Second string `gorm:"uniqueIndex:idx_first_second"`
}