'Golang: Gorm Error on insert or update on table violates foreign key contraint
Im trying to create a REST service using Gorm that on startup will drop the database tables from my Postgres DB and then create and populate them with test data. The entities I am using are as follows:
type Group struct {
ID uuid.UUID `gorm:"PrimaryKey" json:"id"`
Name string `json:"name"`
Sessions []Session `gorm:"foreignKey:ID" json:"sessions"`
}
type Session struct {
ID uuid.UUID `gorm:"PrimaryKey"`
GroupID uuid.UUID `gorm:"foreignKey:ID"`
Name string
From time.Time
To time.Time
}
type Player struct {
ID uuid.UUID `gorm:"PrimaryKey" json:"id"`
Sessions []Session `gorm:"many2many:players_sessions" json:"sessions"`
Groups []Group `gorm:"many2many:players_groups" json:"groups"`
Username string `gorm:"type:varchar;NOT NULL" json:"username"`
Cookie string `json:"cookie"`
}
On startup, when the tables have been dropped they are recreated and populated using this code:
func PopulateDB(db *gorm.DB) {
db.AutoMigrate(&entities.Group{}, &entities.Player{}, &entities.Session{})
players := []entities.Player{
{ID: uuid.New(), Username: "Player 1", Cookie: ""},
{ID: uuid.New(), Username: "Player 2", Cookie: ""},
{ID: uuid.New(), Username: "Player 3", Cookie: ""},
}
for index := range players {
db.Create(&players[index])
}
group := entities.Group{ID: uuid.New(), Name: "My Group"}
db.Create(&group)
sessions := []entities.Session{
{
ID: uuid.New(),
GroupID: group.ID,
Name: "Session 1",
From: time.Now(),
To: time.Now().Add(12 * time.Hour),
},
{
ID: uuid.New(),
GroupID: group.ID,
Name: "Session 2",
From: time.Now().Add(24 * time.Hour),
To: time.Now().Add(36 * time.Hour),
},
}
for index := range sessions {
db.Model(&group).Association("Sessions").Append(&sessions[index])
// db.Create(&sessions[index])
}
// Make player >-< groups connections
for index := range players {
db.Model(&players[index]).Association("Groups").Append(&group)
}
// Make player >-< session connections
for index := range players {
db.Model(&players[index]).Association("Sessions").Append(&sessions[0])
if index%2 == 0 {
db.Model(&players[index]).Association("Sessions").Append(&sessions[1])
}
}
}
The issue I am having is that when the test data is inserted it returns the following error: ERROR: insert or update on table "sessions" violates foreign key constraint "fk_groups_sessions" (SQLSTATE 23503)
. This occurs on the line db.Model(&group).Association("Sessions").Append(&sessions[index])
.
I'm under the impression that this is being caused by trying to insert a Session without a valid Group foreign key, but I'm not knowledgeable enough with Gorm to understand what I'm doing wrong. Any help would be much appreciated!
Solution 1:[1]
type Group struct {
ID uuid.UUID `gorm:"PrimaryKey" json:"id"`
Name string `json:"name"`
Sessions []Session `gorm:"foreignKey:GroupID" json:"sessions"
}
type Session struct {
ID uuid.UUID `gorm:"PrimaryKey"`
GroupID uuid.UUID `gorm:"foreignKey:ID"`
Name string
From time.Time
To time.Time
}
This should fix it, the reference is changed from ID to GroupID
Solution 2:[2]
If this is your database schema design, it should be like this.
type Group struct {
ID uuid.UUID `gorm:"primaryKey"`
Name string `gorm:"column:name"`
}
type Session struct {
ID uuid.UUID `gorm:"primaryKey"`
GroupID uuid.UUID `gorm:"column:group_id"
Group Group `gorm:"foreignKey:ID"`
Name string `gorm:"column:name"`
From time.Time `gorm:"column:from"`
To time.Time `gorm:"column:to"`
}
type Player struct {
ID uuid.UUID `gorm:"primaryKey"`
Username string `gorm:"column:username;type:varchar;NOT NULL"`
Cookie string `gorm:"column:cookie"`
SessionID uuid.UUID `gorm:"column:session_id"`
GroupID uuid.UUID `gorm:"column:group_id"`
Sessions []Session `gorm:"many2many:players_sessions;foreignKey:SessionID;references:ID;"`
Groups []Group `gorm:"many2many:players_groups;foreignKey:GroupID;references:ID;"`
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | EKivutha |
Solution 2 | Jayson LP Chen |