【发布时间】:2017-05-10 16:37:37
【问题描述】:
我正在使用一个尚未标准化的数据库,该表包含超过 40 列的记录。
以下是我的 Go 代码,用于(尝试)将记录扫描到一个大型结构中:
type Coderyte struct {
ID int `json:"id"`
EmrID int `json:"emr_id"`
DftID int `json:"dft_id"`
Fix int `json:"fix"`
ReportDate string `json:"report_date"` // Time?
Patient string `json:"patient"`
... // etc
}
func ReadCoderyte(res http.ResponseWriter, req *http.Request) {
rows, err := db.Query("SELECT * FROM coderyte")
if err != nil {
http.Error(res, "Error querying database", 500)
}
defer rows.Close()
// Convert rows into a slice of Coderyte structs
coderytes := make([]*Coderyte, 0)
for rows.Next() {
coderyte := new(Coderyte)
err := rows.Scan(&coderyte) // Expected 42 columns
if err != nil {
panic(err)
http.Error(res, "Error converting coderyte object", 500)
}
coderytes = append(coderytes, coderyte)
}
当我调用此代码时,Scan 抱怨它“需要 42 个目标参数,而不是 1 个”。我的理解是,我需要在扫描调用内部处理这个大型结构中的每个字段,即Scan(&coderyte.ID, &coderyte.EmrID, etc)
我的搜索只产生了this other question,建议的答案是使用sqlx。如果不需要,我会尽量避免使用第三方工具。
我的问题归结为:有没有办法在不指定每个字段的情况下将大型数据库记录转换为结构?。
我还应该注意,这个函数的最终目标是返回一个 JSON 对象数组,但我没有包含那部分代码,因为我觉得它并不重要。如果有办法绕过Scan 并返回 JSON,那也是一个值得赞赏的答案。
【问题讨论】:
-
简短回答:不。长答案:我也推荐 sqlx。标准库不支持解组为结构。
-
我也有同样的建议。
-
是的,不支持,但如果你仍然想使用标准的 sql 包,我建议阅读go-database-sql.org/retrieving.html
-
RE:您问题的第二部分:我制作了一个小包,我在所有地方都使用了这个包。如果您想检查一下,这非常简单,我在这里总结了一下:gist.github.com/heyimalex/075bb442af0ecbf3e5f561336101e4f7
-
@AlexGuerra 必须为
sqlx制作和标记结构可能很烦人,但利用该方法的类型安全性有其优势。