我有一个接受SQL查询的服务,使用数据库/ sql驱动程序在Amazon Redshift上运行查询。但是,我无法将结果转换为结构,因为查询是各种表上的大数据任务,而不是在此服务中创建的。因此,我必须返回一个“松散”的数据结构。我正在解析返回JSON的数据并将其存储在S3中。
但是,我在返回的数据类型上遇到了一些奇怪的问题。对于数字列的查询将返回uint8的映射,而不是数字值。我知道这是因为数据库驱动程序无法确定将其转换为什么,因为它可能不精确。但是我似乎也无法在[] uint8和整数之间进行转换。
这是我查询数据库的代码:
// Execute executes SQL commands
func (r *Runner) Execute(query string, args ...interface{}) (types.Results, error) {
var results types.Results
rows, err := r.db.Query(query, args...)
if err != nil {
return results, err
}
columns, _ := rows.Columns()
colNum := len(columns)
values := make([]interface{}, colNum)
for i := range values {
var ii interface{}
values[i] = &ii
}
for rows.Next() {
rows.Scan(values...)
result := make(types.Result)
for i, colName := range columns {
rawValue := *(values[i].(*interface{}))
if reflect.TypeOf(rawValue).String() == "[]uint8" {
byteVal := rawValue.([]byte)
val := Intfrombytes(byteVal)
log.Println("Converted:", val)
}
result[colName] = rawValue
}
results = append(results, result)
}
return results, nil
}
我创建了以下函数,尝试在[]uint8
和uint32
之间进行转换。
func Intfrombytes(bytes []uint8) uint16 {
bits := binary.LittleEndian.Uint16(bytes)
return bits
}
但是,如果我将200
插入到该表中,则会返回12339
。通常,这种方法感觉很不稳定。我在处理未定义的,松散的数据结构时怀疑使用Go的决定。
是否有更好的方法来处理通用查询(例如我的示例),或者是否可以将数字结果转换为整数?
答案 0 :(得分:1)
我认为您实际上可能在解释一个字符串([] uint8 == [] byte)。参见https://play.golang.org/p/Rfpey2NPiI7
originalValue := []uint8{0x32, 0x30, 0x30} // "200"
bValue := []byte(originalValue) // byte is a uint8 anyway
fmt.Printf("Converted to uint16: %d\n", binary.LittleEndian.Uint16(bValue))
fmt.Printf("Actual value: %s", string(bValue))
在处理pq
和一些加密代码之前,这让我很痛苦。