Writing a webserver in Golang with gorm & postgres, I got stuck misunderstanding what's exactly going on at the second loop iteration in the following code:
...
for _, t := range tasks {
newDbConn := db.SchoolServerDB.Debug().New()
err = newDbConn.Where("id = ?", t.DayID).First(&day).Error
if err != nil {
return errors.Wrapf(err, "Error query day with id='%v'", t.DayID)
}
...
}
...
First iteration debug:
SELECT * FROM "days" WHERE "days"."deleted_at" IS NULL AND ((id = '8')) ORDER BY "days"."id" ASC LIMIT 1
Second iteration debug:
SELECT * FROM "days" WHERE "days"."deleted_at" IS NULL AND "days"."id" = '8' AND ((id = '38')) ORDER BY "days"."id" ASC LIMIT 1
The key question is: why search conditions are accumulated despite there's a new connection being created each iteration? According to docs search conditions must be cleared every time. I'd like to get the second result like this:
SELECT * FROM "days" WHERE "days"."deleted_at" IS NULL AND ((id = '38')) ORDER BY "days"."id" ASC LIMIT 1
Any help appreciated!
UPD:
db.SchoolServerDb is just *gorm.DB and Debug() is its method
Table 'days' is made of struct Day:
type Day struct {
gorm.Model
StudentID uint // parent id
Date string `sql:"size:255"`
Tasks []Task // has-many relation
Lessons []Lesson // has-many relation
}
There is no problem with your Search Condition. Simply you have provided multiple IDs in your queries from second iteration. One in Where
and another in Find
.
Let me write an example like yours
ids := []int{1, 2}
var org database.Organization
for _, i := range ids {
db, _ := connection.NewPGConnection(info)
db = db.Debug().New()
db.Where("id = ?", i).Find(&org)
}
Here, SQL query in first iteration is as below:
SELECT * FROM "organizations" WHERE "organizations"."deleted_at" IS NULL AND ((id = '1'))
And in second iteration it will be:
SELECT * FROM "organizations" WHERE "organizations"."deleted_at" IS NULL AND "organizations"."id" = '1' AND "organizations"."code" = 'mir' AND ((id = '2'))
Why? Because, you have used same variable day, to read row result.
First time, Its ok. But second time, your day variable has already an ID in it. And you have provide another one in Where
. Thats why, its running query with two ids.
You are actually providing two
id
, one inwhere
clause and another inFind
.
Change your code to redeclare your variable day each time. Like this.
ids := []int{1, 2}
for _, i := range ids {
db, _ := connection.NewPGConnection(info)
db = db.Debug().New()
var org database.Organization // <----- move your variable day here
db.Where("id = ?", i).Find(&org)
}
Each time, new and clean variable will be used. And your problem will be solved.
Thank you. Hope this will help you.