You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用blob作为分区键时gocql反序列化失败问题求助

解决gocql查询Cassandra Blob类型分区键时的反序列化问题

我来帮你搞定这个问题——你碰到的can not unmarshal blob into *[20]uint8错误,核心原因是查询参数的类型不匹配,以及gocql对Blob类型和Go数组类型的映射规则。咱们一步步拆解解决:

问题根源

你用fmt.Sprintf把SHA1哈希([20]uint8类型)转成了十六进制字符串(比如0xd03dde1610d6df87a90619412ceda6e5320528dd),然后把这个字符串作为查询参数传给Cassandra。但Cassandra的Blob类型存储的是二进制数据,gocql需要直接接收二进制类型的参数,而不是格式化后的字符串。另外,当你用*[20]uint8接收返回值时,需要确保查询返回的二进制数据能直接映射到这个数组类型。

解决方案

1. 直接传递二进制参数,而非十六进制字符串

SHA1的Sum方法返回的是[20]uint8,你可以直接把它转换成[]byte(切片)作为查询参数,不需要转成十六进制字符串。gocql会自动把[]byte映射到Cassandra的Blob类型。

2. 正确接收返回值

你可以用[20]uint8变量直接接收返回的Blob数据,或者先接收成[]byte再复制到数组里(两种方式都可行)。

修正后的代码示例

下面是调整后的完整查询代码,包括可能的插入逻辑(确保数据正确存储):

package main

import (
	"fmt"
	"log"
	"crypto/sha1"

	"github.com/gocql/gocql"
)

func main() {
	cluster := gocql.NewCluster("10.0.0.1")
	cluster.Keyspace = "ks"
	cluster.Consistency = gocql.Quorum
	cluster.ProtoVersion = 4
	cluster.Authenticator = gocql.PasswordAuthenticator{
		Username: "cassandra",
		Password: "cassandra",
	}
	session, err := cluster.CreateSession()
	if err != nil {
		log.Fatalf("Failed to create session: %v", err)
	}
	defer session.Close()

	text := "text before hashed"
	data := []byte(text)
	// SHA1哈希得到[20]uint8
	hashValue := sha1.Sum(data)

	// 先确保数据已经正确插入(如果之前没插入的话)
	insertQuery := `INSERT INTO sample (hash_value, column1) VALUES (?, ?)`
	err = session.Query(insertQuery, hashValue[:], 123).Exec()
	if err != nil {
		log.Fatalf("Insert failed: %v", err)
	}
	fmt.Println("Data inserted successfully")

	// 执行查询:直接传递[]byte类型的参数
	var returnedHash [20]uint8
	var column1 int
	query := `SELECT hash_value, column1 FROM sample WHERE hash_value = ? LIMIT 1`
	err = session.Query(query, hashValue[:]).Consistency(gocql.One).Scan(&returnedHash, &column1)
	if err != nil {
		log.Fatalf("Query failed: %v", err)
	}

	// 验证结果
	fmt.Printf("Returned hash: %v\n", returnedHash)
	fmt.Printf("Returned column1: %d\n", column1)
	// 对比原始哈希和返回的哈希
	if returnedHash == hashValue {
		fmt.Println("Hash matches!")
	}
}

关键注意点

  • 插入数据时:同样要传递hashValue[:]([]byte类型),而不是十六进制字符串,确保Cassandra存储的是正确的Blob二进制数据。
  • 查询参数:绝对不要用格式化后的十六进制字符串(比如0x...),直接用二进制切片即可。
  • 类型匹配:gocql可以自动在Cassandra Blob和Go的[]byte、[N]uint8之间转换,只要参数和接收变量的类型对应上就不会报错。

内容的提问来源于stack exchange,提问作者simotunes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:46:19