英文:
How to get JSON data from MySQL with correct field type?
问题
我是一个初学者,正在学习Golang。我阅读了很多关于从MySQL数据库获取JSON的线程,但还有一个问题没有得到解答:JSON中所有字段的值都是字符串,而不是它们正确的类型,无论是整数还是时间。
我正在使用的代码如下:
var emptyOut []byte
rows, err := db.Query(sqlString)
if err != nil {
return emptyOut, err
}
defer rows.Close()
columns, err := rows.Columns()
if err != nil {
return emptyOut, err
}
count := len(columns)
tableData := make([]map[string]interface{}, 0)
values := make([]interface{}, count)
valuePtrs := make([]interface{}, count)
for rows.Next() {
for i := 0; i < count; i++ {
valuePtrs[i] = &values[i]
}
rows.Scan(valuePtrs...)
entry := make(map[string]interface{})
for i, col := range columns {
var v interface{}
val := values[i]
b, ok := val.([]byte)
if ok {
v = string(b)
} else {
v = val
}
entry[col] = v
}
tableData = append(tableData, entry)
}
jsonData, err := json.Marshal(tableData)
if err != nil {
return emptyOut, err
}
return jsonData, nil
将数据转换为字符串的部分肯定是这一段:
v = string(b)
所以问题是:如何将v转换为正确的b值类型。这将节省我在以后处理错误字段类型时的大量工作。提前谢谢!
英文:
I am a beginner to Golang. I've read many threads about getting JSON from a mysql database, but there is a question left unanswered: the values of all fields in the JSON are strings and not their correct types, be it integer or time.
The code I'm using:
var emptyOut []byte
rows, err := db.Query(sqlString)
if err != nil {
return emptyOut, err
}
defer rows.Close()
columns, err := rows.Columns()
if err != nil {
return emptyOut, err
}
count := len(columns)
tableData := make([]map[string]interface{}, 0)
values := make([]interface{}, count)
valuePtrs := make([]interface{}, count)
for rows.Next() {
for i := 0; i < count; i++ {
valuePtrs[i] = &values[i]
}
rows.Scan(valuePtrs...)
entry := make(map[string]interface{})
for i, col := range columns {
var v interface{}
val := values[i]
b, ok := val.([]byte)
if ok {
v = string(b)
} else {
v = val
}
entry[col] = v
}
tableData = append(tableData, entry)
}
jsonData, err := json.Marshal(tableData)
if err != nil {
return emptyOut, err
}
return jsonData, nil
The part that turns data into string is surely this one:
v = string(b)
So the question is: how to turn v into the right type of value of b. This will save a lot of my effort in dealin with wrong field type later on. Thank you in advance!
答案1
得分: 1
我对你的问题的限制条件还有一些不太清楚。
如果你事先知道数据库的模式,我建议创建一个表示数据的结构体。然后你可以使用数据库库gorm将数据获取到一个结构体切片中。你可以给结构体添加go tags,并将结构体切片转换为JSON,其中字段被正确地编组为它们的正确类型。
例如(未经测试):
type MyDataSchema struct {
Id int `json:"id"`
Name string `json:"name"`
Birth time.Time `json:"birth_date,omitempty"`
}
...
rows := &[]MyDataSchema{}
result := db.Find(&rows)
b, err := json.Marshal(result)
如果你事先不知道模式,那就有点棘手了。在Go语言中有一种叫做type switch的东西,你可能需要考虑使用它:
如果我正确理解你的代码,val := values[i]
中的val
是一个接口类型。所以你可以这样做(未经测试):
switch v := i.(type) {
case int:
entry[col] = v
case string:
entry[col] = v
case time.Time:
entry[col] = v
//你可以添加更多的类型
default:
entry[col] = val
}
这可能不是一个完整的答案,但希望能帮助你解决问题。
英文:
I am a little unclear on the constraints of your problem.
If you know the database schema before hand, I would create a struct that represents your data. You can then use the database library gorm to get the data into a struct slice. You can add go tags to the struct and convert the struct slice to json with the fields marshaled into their correct types.
For example (untested):
type MyDataSchema struct {
Id int `json:"id"`
Name string `json:"name"`
Birth time.Time `json:"birth_date,omitempty"`
}
...
rows:=&DataSchema{}
result := db.Find(&rows)
b, err := json.Marshal(result)
If you dont know the schema before hand, then it is a little bit more tricky. In go there is such a thing as a type switch. You might want to consider that:
If I am following your code correctly, val := values[i]
val is of type interface. So you could do something like (untested):
switch v := i.(type) {
case int:
entry[col]=v
case string:
entry[col]=v
case time.Time:
entry[col]=v
//you can add more types
default:
entry[col]=val
}
This might not be a complete answer but hopefully it gets you to where you need.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论