今天我给大家带来一篇《Redshift 返回 uint8 而不是整数,它们之间的转换会返回错误的值》,本文主要会讲到等等知识点,希望大家一起学习进步,也欢迎大家关注、点赞、收藏、转发! 下面就一起来看看吧!
问题内容
我有一项服务,它接受 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 来完成此任务,因为我正在处理未定义的松散数据结构。
有没有更好的方法来处理通用查询(例如我的示例),或者有没有办法可以将数字结果转换为整数?
解决方案
实际上,我认为您可能正在解释一个字符串 ([]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 和一些加密代码时,这已经困扰了我。
好了,本文到此结束,带大家了解了《Redshift 返回 uint8 而不是整数,它们之间的转换会返回错误的值》,希望本文对你有所帮助!