我如何根据不可预测的 db.Query() 创建新结构?
How could I create a new struct from an unpredictable db.Query()?
我在 table 的 db.query()
到 return 列中使用 SELECT *
。通常,我会将 fmt.Scan()
行放入预先声明的 struct{}
中以进行进一步操作,但在这种情况下, table 列经常更改,因此我无法使用声明的 struct{}
作为我的 Scan()
.
的一部分
我一直在努力弄清楚如何根据 db.query()
的列结果动态构建 struct{}
,随后我可以调用 for Scan()
].我已经阅读了一些关于 reflect
的内容,但我正在努力确定这是否适合我的用例,或者我是否需要考虑其他事情。
任何指点将不胜感激。
您可以从生成的行集中获取列名并为扫描准备切片。
示例(https://go.dev/play/p/ilYmEIWBG5S):
package main
import (
"database/sql"
"fmt"
"log"
"github.com/DATA-DOG/go-sqlmock"
)
func main() {
// mock db
db, mock, err := sqlmock.New()
if err != nil {
log.Fatal(err)
}
columns := []string{"id", "status"}
mock.ExpectQuery("SELECT \* FROM table").
WillReturnRows(sqlmock.NewRows(columns).AddRow(1, "ok"))
// actual code
rows, err := db.Query("SELECT * FROM table")
if err != nil {
log.Fatal(err)
}
cols, err := rows.Columns()
if err != nil {
log.Fatal(err)
}
data := make([]interface{}, len(cols))
strs := make([]sql.NullString, len(cols))
for i := range data {
data[i] = &strs[i]
}
for rows.Next() {
if err := rows.Scan(data...); err != nil {
log.Fatal(err)
}
for i, d := range data {
fmt.Printf("%s = %+v\n", cols[i], d)
}
}
}
此示例将所有列读入字符串。要检测列类型,可以使用 rows.ColumnTypes
方法。
我在 table 的 db.query()
到 return 列中使用 SELECT *
。通常,我会将 fmt.Scan()
行放入预先声明的 struct{}
中以进行进一步操作,但在这种情况下, table 列经常更改,因此我无法使用声明的 struct{}
作为我的 Scan()
.
我一直在努力弄清楚如何根据 db.query()
的列结果动态构建 struct{}
,随后我可以调用 for Scan()
].我已经阅读了一些关于 reflect
的内容,但我正在努力确定这是否适合我的用例,或者我是否需要考虑其他事情。
任何指点将不胜感激。
您可以从生成的行集中获取列名并为扫描准备切片。
示例(https://go.dev/play/p/ilYmEIWBG5S):
package main
import (
"database/sql"
"fmt"
"log"
"github.com/DATA-DOG/go-sqlmock"
)
func main() {
// mock db
db, mock, err := sqlmock.New()
if err != nil {
log.Fatal(err)
}
columns := []string{"id", "status"}
mock.ExpectQuery("SELECT \* FROM table").
WillReturnRows(sqlmock.NewRows(columns).AddRow(1, "ok"))
// actual code
rows, err := db.Query("SELECT * FROM table")
if err != nil {
log.Fatal(err)
}
cols, err := rows.Columns()
if err != nil {
log.Fatal(err)
}
data := make([]interface{}, len(cols))
strs := make([]sql.NullString, len(cols))
for i := range data {
data[i] = &strs[i]
}
for rows.Next() {
if err := rows.Scan(data...); err != nil {
log.Fatal(err)
}
for i, d := range data {
fmt.Printf("%s = %+v\n", cols[i], d)
}
}
}
此示例将所有列读入字符串。要检测列类型,可以使用 rows.ColumnTypes
方法。