在扫描数据库行时,错误“类型[] uint8的值不能分配给类型[]字符串”

时间:2014-06-30 23:07:47

标签: postgresql go

我使用postgresql作为我的后端数据库。

尝试扫描字段语言,这是一个文本数组

    var user userprofile

row := core.db.QueryRow("SELECT languagespoken FROM \"user\" WHERE id = $1",userId)

err := row.Scan(&user.Languages)

if err != nil {
    return user,err
}

我的结构在golang中看起来像这样

   type userprofile struct {
    Languages []string `json:languages`
    }

但是得到了错误

2014/06/30 15:27:17 PANIC: reflect.Set: **value of type []uint8 is not assignable to type []string**
/usr/lib/go/src/pkg/reflect/value.go:2198 (0x56c152)
    Value.assignTo: panic(context + ": value of type " + v.typ.String() + " is not assignable to type " + dst.String())
/usr/lib/go/src/pkg/reflect/value.go:1385 (0x56966b)
    Value.Set: x = x.assignTo("reflect.Set", v.typ, target)
/usr/lib/go/src/pkg/database/sql/convert.go:215 (0x492d70)
    convertAssign: dv.Set(sv)
/usr/lib/go/src/pkg/database/sql/sql.go:1562 (0x49c0e5)
    (*Rows).Scan: err := convertAssign(dest[i], sv)
/usr/lib/go/src/pkg/database/sql/sql.go:1630 (0x49c560)
    (*Row).Scan: err := r.rows.Scan(dest...)
/home/ceresti/source/gocode/src/ceresti.kilnhg.com/ceresti/server/app/databaseapi.go:144 (0x402478)
    (*coreStruct).GetUserProfile: err := row.Scan(&user.Languages)
/home/ceresti/source/gocode/src/ceresti.kilnhg.com/ceresti/server/app/restfulapi.go:327 (0x40a63c)
    Getuserprofile: userprofileStruct, err := core.GetUserProfile(userId)
/usr/lib/go/src/pkg/runtime/asm_amd64.s:340 (0x4309c2)

请告诉我如何解决此问题。

2 个答案:

答案 0 :(得分:3)

并非所有sql数据库都指定数组类型(例如,sqlite3)。 Go不直接支持任何sql实现,但它提供了一个与实现无关的接口(在该词的一般意义上),可以为其编写第三方驱动程序。 Go并没有对其驱动程序可能支持的类型施加任何限制,因此如果某种类型不合作,则可能是驱动程序的错误。

TL; DR:尝试将其作为字符串

// if `string` doesn't work, try `[]uint8` or `[]byte` and then convert
// that output to a string if necessary
var languages string
if err := row.Scan(&languages); err != nil {
    // handle error
}

// depending on how the string is encoded, this may or may not work
// Update: since you say your list is encoded in the form:
// `{elem1, elem2, elem3}`, we'll simply ignore the first and last
// characters and split on ", "
user.Languages = strings.Split(languages[1:len(languages)-1], ", ")

答案 1 :(得分:2)

您似乎试图一次性扫描该数据库查询的整个结果集。你做不到;您需要一次一个地读取每一行,然后将字节切片转换为字符串。

由于您要序列化为[]string,因此每次保存字节切片不是优先事项。在这种情况下,您可以使用sql.RawBytes代替[]byte,这将重复使用相同的内存。

// error checking elided
var row sql.RawBytes
myRow.Scan(&row) // note the pointer!
str := string(row)