Gorm with golang: Preload does not work as expected - go

I have following structs
type Employee struct {
EmployeeID int64 `gorm:"primary_key;column:employee_id"`
EmployeeCode string `gorm:"column:employee_code"`
FirstName string `gorm:"column:first_name"`
LastName string `gorm:"column:last_name"`
DesignationID int64 `gorm:"column:designation_id;"`
Designation *Designation
}
type Designation struct {
DesignationID int64 `gorm:"primary_key;column:designation_id"`
DesignationName string `gorm:"column:designation_name"`
}
func GetEmployee(id int64) (*Employee, error) {
db := connection.GetConn() //get connection
defer db.Close()
employee := &Employee{}
err := db.Model(employee).Preload("Designation").Find(employee).Error
return employee, err
}
In the tables I have following records:
employee :
employee_id | employee_code | first_name | last_name | designation_id
1 | EMP1 | Raj | Mane | 1
designation:
designation_id | designation_name
1 | Engineer
The employee.designation_id is marked as foreign key referring to designation table
When I call the function GetEmployee, it returns error saying can't preload field Designation for model.Employee
I have referred many questions related to Preload but none of the solution has worked. I think only difference between the other working cases is the primary id column name. Can anyone suggest what is happening and what am I missing here?

In GORM default foreign key uses owner’s type name plus its primary key.
GORM provides a way to customize the foreign key, for example:
type Employee struct {
EmployeeID int64 `gorm:"primary_key;column:employee_id"`
EmployeeCode string `gorm:"column:employee_code"`
FirstName string `gorm:"column:first_name"`
LastName string `gorm:"column:last_name"`
DesignationID int64 `gorm:"column:designation_id;"`
Designation *Designation `gorm:"foreignkey:DesignationID"`
}

Just simply change your variable name from DesignationID to DesignationDesignationID. It will work. As per document ForignKey must be TABLE_NAME + PRIMARY_KEY_NAME so here table is DESIGNATION and primary key DESIGNATIONID
type Employee struct {
EmployeeID int64 `gorm:"primary_key;column:employee_id"`
EmployeeCode string `gorm:"column:employee_code"`
FirstName string `gorm:"column:first_name"`
LastName string `gorm:"column:last_name"`
DesignationDesignationID int64
Designation *Designation
}
type Designation struct {
DesignationID int64 `gorm:"primary_key;`
DesignationName string `gorm:"column:designation_name"`
}

Related

Gorm preload gives ambiguous column error

I have following structs
type Employee struct {
EmployeeID int64 `gorm:"primary_key;column:employee_id"`
EmployeeCode string `gorm:"column:employee_code"`
FirstName string `gorm:"column:first_name"`
LastName string `gorm:"column:last_name"`
DesignationID int64 `gorm:"column:designation_id;"`
Designation *Designation `gorm:"foreignkey:DesignationID"`
}
type Designation struct {
DesignationID int64 `gorm:"primary_key;column:designation_id"`
DesignationName string `gorm:"column:designation_name"`
}
func GetEmployee(id int64) (*Employee, error) {
db := connection.GetConn() //get connection
defer db.Close()
employee := &Employee{}
err := db.Model(employees).Preload("Designation", func(db *gorm.DB) *gorm.DB {
return db.Join("INNER JOIN employees ON employees.designation_id = designations.id").Order("employees.first_name DESC")
}).Find(employee).Error
return employee, err
}
The query that gets generated is
SELECT * FROM employees;
SELECT * FROM designations INNER JOIN employees ON employees.designation_id = designations.id WHERE id IN (1,2) order by employees.first_name DESC;
I have a join which is similar to what I have written in above function. Here I am not able to justfiy the join but in actual case I know that join is required and the preloading table and the join table both have id field in them.
Since both tables have same column name i.e. id in that case MYSQL throws error saying
Error 1052: Column 'id' in where clause is ambiguous
I am facing this issue in gorm v1.9.16
I have not found any resource where similar issue is mentioned.
How do we solve this issue?
Could you try with a recent version (> v1.20.x)?
The issue has been closed https://github.com/go-gorm/gorm/issues/2653
The issue seems to be fixed in the new version https://github.com/go-gorm/gorm/commit/2ae0653af2bc19cd31f687e797b189c85f0ac3f6

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 2, Golang, Auto migrate table with foreign key

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

pq: insert or update on table violates foreign key constraint gorm

I have three tables: AnaData, AnaStepData, and AnaStepInputData. Here are the model mappings for these tables:
type AnaData struct {
ID string `gorm:"primary_key;column:ana_ins_id" validate:"max=36"`
Name string `gorm:"column:instance_nm" validate:"max=36"`
Description string `gorm:"column:instance_desc" validate:"max=1000"`
AnaSteps []AnaStepData `gorm:"foreignkey:ana_ins_id"`
}
type AnaStepData struct {
ID string `gorm:"primary_key;column:ana_ins_step_id" validate:"max=36"`
StepName string `gorm:"column:step_nm" validate:"max=100"`
AnaInsID string `gorm:"column:ana_ins_id" validate:"max=36"`
InputParameters []AnaStepInputData `gorm:"foreignkey:ana_ins_step_id"`
}
type AnaStepInputData struct {
ID string `gorm:"primary_key;column:ana_ins_step_input_id" validate:"max=36"`
AnaStepID string `gorm:"column:ana_ins_step_id" validate:"max=36"`
ParameterName string `gorm:"column:ana_param_nm" validate:"max=100"`
ParameterValue string `gorm:"column:param_value_txt" validate:"max=1000"`
}
When I try to insert any values using "db.Create(&AnaData) into the AnaData table and respective child tables, I get the following error:
pq: insert or update on table "ana_ins_step_input" violates foreign
key constraint "ana_ins_step_input_fk02"
Can anyone shed some light on what I am doing wrong?

Gorm extra where 1 <> 1 in many2many

I have two models (structs). User and Group. Those models have many to many relationships.
When I try to create query db.Unscoped().Model(&group).Related(&users, "Users") this returns:
SELECT users.* FROM users INNER JOIN user_groups ON user_groups.owner_id = users.id WHERE (1 <> 1)
The entities are:
type Group struct {
gorm.Model
ID uint `json:"id"`
Name string `json:"name"`
Users []User `gorm:"many2many:user_groups;association_jointable_foreignkey:owner_id"`
}
type User struct {
...
Groups []Group `gorm:"many2many:user_groups;association_jointable_foreignkey:group_id"`
}
Handler
users := []models.User{}
group := models.Group{}
db.Unscoped().Model(&group).Related(&users, "Users")
I don't know the reason to generate extra where.
The problem is fixed.
I have eliminated gorm.Model in struct:
type Group struct {
ID uint `json:"id"`
Name string `json:"name"`
Users []User `gorm:"many2many:user_groups;association_jointable_foreignkey:owner_id"`
}
And In the query:
db.Model(&group).Related(&users)
Regards.

Resources