Gorm 2, Golang, Auto migrate table with foreign key - go

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{})

Related

GORM: unsupported Scan, storing driver.Value type int64 into type *models.Team

I have issue with my first GORM usage. I want to load Point with preloaded Team structure. Go throw error that int64 cannot be stored in models.Team. I suppose that I have to use GORM the wrong way, but I am not able to find out why. Database contain data, relation many2many on other structs works fine for me (users in Team struct).
type Point struct {
Id int `gorm:"primaryKey"`
TeamX Team `gorm:"column:team_id;foreignKey:id"` // <<< this struct I want to get
CreatedAt time.Time
Note string
}
func (Point) TableName() string {
return "points"
}
type Team struct {
Id int `gorm:"primaryKey"`
Name string
Users []User `gorm:"many2many:teams_users;"`
}
func (Team) TableName() string {
return "teams"
}
var obj models.Point
log.Println(getDatabase().Preload("Teams").First(&obj, 1).Error.Error())
fmt.Println(obj.Id) // <<< this one loads ok
fmt.Println(obj.TeamX.Id) // <<< this throw error
points table
id int(11), auto_increment
team_id int(11), foreign key teams(id)
createdAt datetime
note text
teams table
id int(11), auto_increment
name text
sql: Scan error on column index 1, name "team_id": unsupported Scan, storing driver.Value type int64 into type *models.Team

GORM foreign keys without embedded struct

So, using GORM I realize that to use foreign keys, I have to embed the struct in another struct, otherwise gorm won't recognize the relationship like this:
type People struct {
ID int
Name string
Card []Card
}
type Card struct {
ID int
Name string
PeopleID int
}
But, i don't actually want this embeding system. For me, it becomes more troublesome to do sanitization when developing REST apis. So, is there a way to tell GORM about the relationship without actually having to have an embedded struct onto another? Like:
type People struct {
ID int
Name string
//No `Card` object here
}
type Card struct {
ID int
Name string
PeopleID int `gorm:"foreignKey:People.ID` //Something like this
}

Specify key for many-to-many relationship in go-pg ORM

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"`
}

How can I remove a 'Belongs To' association in jinzhu/gorm

Can anyone help me, how to remove a belongs to association in go-gorm?
Here are my simple models:
type User struct {
gorm.Model
Name string
FirstName string
}
type Customer struct {
Notes []Note `gorm:"polymorphic:Owner;"` // other models can have notes as well
}
type Note struct {
gorm.Model
User User `json:"-"`
UserID uint
OwnerID uint
OwnerType string
}
For "Has many" and "Many to many" associations I can remove the relations. In this example, this works:
db.Model(&customer).Association("Notes").Delete(&note)
However, if I try following:
db.Model(&note).Association("User").Delete(&user)
I get a pointer error:
panic: runtime error: index out of range
... src/github.com/jinzhu/gorm/association.go:242 +0x21ce
The ''user'' and ''note'' objects exist and the relation is there (UserID is set to 1 in the database).

How to specify a struct with a multi-column unique index for Gorm?

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"`
}

Resources