我正在使用Gorm构建Go Web API,作为Amazon
RDS中Postgresql数据库的ORM。问题是,尽管数据库中已经填充了数据,但Gorm总是会返回一片全为零的结构。切片中的结构数量适当,具体取决于LIMIT
我给的。
我也尝试过使用database/sql
内置包直接查询SQL
,在rows.Next()
循环内手动插入变量,它没有问题。我用3个不同的表(具有3个不同的结构)尝试了此操作(显然),结果都是相同的。所以我想这在Gorm方面是个问题。该表之一如下所示。
结构结构
type gameCenterLog struct {
tm time.Time
seq int
uid int
partner int
token sql.NullString
bounty int
path1 sql.NullString
path2 sql.NullString
path3 sql.NullString
action sql.NullString
value1 sql.NullString
value2 sql.NullString
value3 sql.NullString
value4 sql.NullString
value5 sql.NullString
}
func (log *gameCenterLog) TableName() string {
return "gamecenter_log"
}
Gorm查询的示例
func testGorm() {
connString := fmt.Sprintf("host=%v port=%v user=%v password=%v dbname=%v", host, port, user, pass, schema)
db, err := gorm.Open("postgres", connString)
if err != nil {
panic(err.Error())
}
defer db.Close()
var logs []gameCenterLog
today := time.Now().UTC()
lastWeek := time.Now().Add(-7 * 24 * time.Hour).UTC()
db.Debug().Where("tm BETWEEN ? AND ?", lastWeek, today).Order("tm desc").Limit(limit).Find(&logs)
fmt.Printf("Error: %+v\n", db.Error)
for _, result := range logs {
fmt.Printf("%+v\n", result)
}
}
政府结果
[2018-08-15 09:57:15] [1429.58ms] SELECT * FROM "gamecenter_log" WHERE (tm BETWEEN '2018-08-08 02:57:14' AND '2018-08-15 02:57:14') ORDER BY tm desc LIMIT 10
[10 rows affected or returned ]
Error: <nil>
{tm:{wall:0 ext:0 loc:<nil>} seq:0 uid:0 partner:0 token:{String: Valid:false} bounty:0 path1:{String: Valid:false} path2:{String: Valid:false} path3:{String: Valid:false} action:{String: Valid:false} value1:{String: Valid:false} value2:{String: Valid:false} value3:{String: Valid:false} value4:{String: Valid:false} value5:{String: Valid:false}}
{tm:{wall:0 ext:0 loc:<nil>} seq:0 uid:0 partner:0 token:{String: Valid:false} bounty:0 path1:{String: Valid:false} path2:{String: Valid:false} path3:{String: Valid:false} action:{String: Valid:false} value1:{String: Valid:false} value2:{String: Valid:false} value3:{String: Valid:false} value4:{String: Valid:false} value5:{String: Valid:false}}
{tm:{wall:0 ext:0 loc:<nil>} seq:0 uid:0 partner:0 token:{String: Valid:false} bounty:0 path1:{String: Valid:false} path2:{String: Valid:false} path3:{String: Valid:false} action:{String: Valid:false} value1:{String: Valid:false} value2:{String: Valid:false} value3:{String: Valid:false} value4:{String: Valid:false} value5:{String: Valid:false}}
{tm:{wall:0 ext:0 loc:<nil>} seq:0 uid:0 partner:0 token:{String: Valid:false} bounty:0 path1:{String: Valid:false} path2:{String: Valid:false} path3:{String: Valid:false} action:{String: Valid:false} value1:{String: Valid:false} value2:{String: Valid:false} value3:{String: Valid:false} value4:{String: Valid:false} value5:{String: Valid:false}}
{tm:{wall:0 ext:0 loc:<nil>} seq:0 uid:0 partner:0 token:{String: Valid:false} bounty:0 path1:{String: Valid:false} path2:{String: Valid:false} path3:{String: Valid:false} action:{String: Valid:false} value1:{String: Valid:false} value2:{String: Valid:false} value3:{String: Valid:false} value4:{String: Valid:false} value5:{String: Valid:false}}
{tm:{wall:0 ext:0 loc:<nil>} seq:0 uid:0 partner:0 token:{String: Valid:false} bounty:0 path1:{String: Valid:false} path2:{String: Valid:false} path3:{String: Valid:false} action:{String: Valid:false} value1:{String: Valid:false} value2:{String: Valid:false} value3:{String: Valid:false} value4:{String: Valid:false} value5:{String: Valid:false}}
{tm:{wall:0 ext:0 loc:<nil>} seq:0 uid:0 partner:0 token:{String: Valid:false} bounty:0 path1:{String: Valid:false} path2:{String: Valid:false} path3:{String: Valid:false} action:{String: Valid:false} value1:{String: Valid:false} value2:{String: Valid:false} value3:{String: Valid:false} value4:{String: Valid:false} value5:{String: Valid:false}}
{tm:{wall:0 ext:0 loc:<nil>} seq:0 uid:0 partner:0 token:{String: Valid:false} bounty:0 path1:{String: Valid:false} path2:{String: Valid:false} path3:{String: Valid:false} action:{String: Valid:false} value1:{String: Valid:false} value2:{String: Valid:false} value3:{String: Valid:false} value4:{String: Valid:false} value5:{String: Valid:false}}
{tm:{wall:0 ext:0 loc:<nil>} seq:0 uid:0 partner:0 token:{String: Valid:false} bounty:0 path1:{String: Valid:false} path2:{String: Valid:false} path3:{String: Valid:false} action:{String: Valid:false} value1:{String: Valid:false} value2:{String: Valid:false} value3:{String: Valid:false} value4:{String: Valid:false} value5:{String: Valid:false}}
{tm:{wall:0 ext:0 loc:<nil>} seq:0 uid:0 partner:0 token:{String: Valid:false} bounty:0 path1:{String: Valid:false} path2:{String: Valid:false} path3:{String: Valid:false} action:{String: Valid:false} value1:{String: Valid:false} value2:{String: Valid:false} value3:{String: Valid:false} value4:{String: Valid:false} value5:{String: Valid:false}}
请注意,所有结果均为零,结果没有错误…
现在用database/sql
func testSQL() {
connString := fmt.Sprintf("host=%v port=%v user=%v password=%v dbname=%v", host, port, user, pass, schema)
db, err := sql.Open("postgres", connString)
if err != nil {
panic(err.Error())
}
defer db.Close()
today := time.Now().UTC()
lastWeek := time.Now().Add(-7 * 24 * time.Hour).UTC()
query := fmt.Sprintf("SELECT * FROM \"%v\" WHERE (%v BETWEEN '%d-%02d-%02d %02d:%02d:%02d' AND '%d-%02d-%02d %02d:%02d:%02d') ORDER BY %v LIMIT %v",
"gamecenter_log", "tm",
lastWeek.Year(), lastWeek.Month(), lastWeek.Day(), lastWeek.Hour(), lastWeek.Minute(), lastWeek.Second(),
today.Year(), today.Month(), today.Day(), today.Hour(), today.Minute(), today.Second(),
"tm desc", limit)
fmt.Println(query)
rows, err := db.Query(query)
if err != nil {
panic(err.Error())
}
results := []gameCenterLog{}
for rows.Next() {
result := gameCenterLog{}
err := rows.Scan(
&result.tm, &result.seq, &result.uid,
&result.partner, &result.token, &result.bounty,
&result.path1, &result.path2, &result.path3, &result.action,
&result.value1, &result.value2, &result.value3, &result.value4, &result.value5,
)
if err != nil {
panic(err.Error())
}
results = append(results, result)
}
for _, result := range results {
fmt.Printf("%+v\n", result)
}
}
在这里,我append
将result
结构手动results
切片
原始SQL结果
SELECT * FROM "gamecenter_log" WHERE (tm BETWEEN '2018-08-08 03:03:41' AND '2018-08-15 03:03:41') ORDER BY tm desc LIMIT 10
{tm:{wall:0 ext:63669899021 loc:0xc420113c20} seq:1534276846269 uid:16199265 partner:1 token:{String:1534274713356-bb09968a07 Valid:true} bounty:3 path1:{String:result Valid:true} path2:{String:Win Valid:true} path3:{String: Valid:false} action:{String: Valid:false} value1:{String: Valid:false} value2:{String: Valid:false} value3:{String: Valid:false} value4:{String: Valid:false} value5:{String: Valid:false}}
{tm:{wall:0 ext:63669899021 loc:0xc420113c20} seq:1534276846278 uid:16060021 partner:15 token:{String:1534272218332-2a6a0a3263 Valid:true} bounty:2 path1:{String:result Valid:true} path2:{String:Win Valid:true} path3:{String: Valid:false} action:{String: Valid:false} value1:{String:102012 Valid:true} value2:{String:68368886 Valid:true} value3:{String: Valid:false} value4:{String: Valid:false} value5:{String: Valid:false}}
{tm:{wall:0 ext:63669899021 loc:0xc420113c20} seq:1534276846275 uid:14565958 partner:6 token:{String:1534277021722-d2f5a72098 Valid:true} bounty:0 path1:{String:track Valid:true} path2:{String:PlayStart Valid:true} path3:{String: Valid:false} action:{String: Valid:false} value1:{String: Valid:false} value2:{String: Valid:false} value3:{String: Valid:false} value4:{String: Valid:false} value5:{String: Valid:false}}
{tm:{wall:0 ext:63669899021 loc:0xc420113c20} seq:1534276846279 uid:16060021 partner:15 token:{String:1534272218332-2a6a0a3263 Valid:true} bounty:0 path1:{String:track Valid:true} path2:{String:PlayEnd Valid:true} path3:{String: Valid:false} action:{String: Valid:false} value1:{String:68368886 Valid:true} value2:{String: Valid:false} value3:{String: Valid:false} value4:{String: Valid:false} value5:{String: Valid:false}}
{tm:{wall:0 ext:63669899021 loc:0xc420113c20} seq:1534276846268 uid:16199265 partner:1 token:{String:1534274713356-bb09968a07 Valid:true} bounty:0 path1:{String:track Valid:true} path2:{String:PlayEnd Valid:true} path3:{String: Valid:false} action:{String: Valid:false} value1:{String: Valid:false} value2:{String: Valid:false} value3:{String: Valid:false} value4:{String: Valid:false} value5:{String: Valid:false}}
{tm:{wall:0 ext:63669899021 loc:0xc420113c20} seq:1534276846270 uid:16199265 partner:1 token:{String:1534274713356-bb09968a07 Valid:true} bounty:0 path1:{String:track Valid:true} path2:{String:Custom Valid:true} path3:{String: Valid:false} action:{String:PemulaGameWin Valid:true} value1:{String:9700600 Valid:true} value2:{String:20000 Valid:true} value3:{String: Valid:false} value4:{String: Valid:false} value5:{String: Valid:false}}
{tm:{wall:0 ext:63669899021 loc:0xc420113c20} seq:1534276846280 uid:7627835 partner:15 token:{String:1534256412228-80b0aacd5b Valid:true} bounty:0 path1:{String:track Valid:true} path2:{String:PlayStart Valid:true} path3:{String: Valid:false} action:{String: Valid:false} value1:{String:66729274 Valid:true} value2:{String: Valid:false} value3:{String: Valid:false} value4:{String: Valid:false} value5:{String: Valid:false}}
{tm:{wall:0 ext:63669899021 loc:0xc420113c20} seq:1534276846277 uid:10212903 partner:4 token:{String:1534270203280-7875331136 Valid:true} bounty:0 path1:{String:track Valid:true} path2:{String:Custom Valid:true} path3:{String: Valid:false} action:{String:ExpertLose Valid:true} value1:{String:+9.50K Valid:true} value2:{String:5000 Valid:true} value3:{String: Valid:false} value4:{String: Valid:false} value5:{String: Valid:false}}
{tm:{wall:0 ext:63669899020 loc:0xc420113c20} seq:1534276846208 uid:13016587 partner:15 token:{String:1534265134142-ed98a488f1 Valid:true} bounty:0 path1:{String:track Valid:true} path2:{String:PlayStart Valid:true} path3:{String: Valid:false} action:{String: Valid:false} value1:{String:67935379 Valid:true} value2:{String: Valid:false} value3:{String: Valid:false} value4:{String: Valid:false} value5:{String: Valid:false}}
{tm:{wall:0 ext:63669899020 loc:0xc420113c20} seq:1534276846265 uid:15125780 partner:1 token:{String:1534267652681-cfb8846eae Valid:true} bounty:0 path1:{String:track Valid:true} path2:{String:Custom Valid:true} path3:{String: Valid:false} action:{String:AhliGameLose Valid:true} value1:{String:-1000000 Valid:true} value2:{String:1000000 Valid:true} value3:{String: Valid:false} value4:{String: Valid:false} value5:{String: Valid:false}}
结果出来没问题。
gameCenterlog
结构中的所有字段均为小写,因此不会导出。非导出字段对反射不可见,因此Gorm对它们不可见。
如果将字段大写:
type gameCenterLog struct {
Tm time.Time
Seq int
Uid int
...
然后Gorm将能够看到它们给出的值。Gorm应该能够弄清楚从PostgreSQL中的列名到Go中的struct字段的映射,但是如果没有,则可以使用gorm:"column:..."
struct标记。
问题内容: 我目前正在制作照片编辑应用。 用户选择了照片后,将使用以下代码将其自动转换为黑白: 我在这段代码中遇到的问题是,我不断收到此错误: 我的代码配置稍有不同,但是到本节时仍然会中断。 是否有任何方法可以从CIImage获取PNG或JPEG数据以用于图像视图(通常仅是UIImage)? 其他任何方法都没有详细说明应使用什么代码。 问题答案: 只需开始一个新的图形上下文并在那里绘制您的灰度图像
问题内容: 我创建了一个自定义错误类型来包装错误,以便更轻松地在Golang中进行调试。当有打印错误时它可以工作,但是现在引起了恐慌。 演示版 当我调用一个函数时,它不会返回错误,我仍然应该能够包装该错误。 预期的行为是,如果错误为nil,则应该简单地忽略它,不幸的是,它会做相反的事情。 我希望它能打印出来。而是即使错误为nil也会打印。 问题答案: 正在将err变量与nil进行比较,但实际上它是
初学者问题,很抱歉,如果这不是一个合适的地方,请尝试学习在中逻辑是如何工作的,我无法理解这一点 我希望它会说“是的!”如果是A、A、D或D,而是z,但出于某种原因,它会说“是的!”无论第一个符号是什么,都会断开,并且只检查第二个符号是否为z。
问题内容: 如果我运行查询,例如: 即使查询与任何记录都不匹配,它也会始终返回结果吗?还是我需要验证并确保结果返回一行? 问题答案: 是的,因为它是一个聚合并且返回零。除非您添加GROUP BY,否则由于没有组,因此没有结果… 除非您添加GROUP BY,然后没有任何行,否则MAX / SUM等将返回NULL。只有COUNT传回没有结果的数字 编辑,有点晚:SUM会像MAX一样返回NULL 编辑,
问题内容: 我正在使用CIFilters将图像转换为灰度并应用一些图像处理效果。在UIImageView中显示输出有效;图像将显示,并且已按预期进行了修改。 但是,每次调用UIImageJPEGRepresentation似乎都不返回任何数据。它永远都行不通。使用原始彩色图像调用UIImageJPEGRepresentation效果很好。 这里发生了什么?为什么在显示图像时jpeg转换会失败?不会
你可以写出返回结构的函数。如,findCenter函数把一个Rectangle类型作为参数,返回一个Point类型的值,其中包含着该矩形中心的坐标: Point findCenter (Rectangle& box) { double x = box.corner.x + box.width/2; double y = box.corner.y + box.height/2;