我有一个带有类型为[]byte
(密码哈希)的模型,我想使用gorm:v2
将其保存在MySQL:5.7
中。
// this will work
type ModelRaw struct {
Bytes []byte
}
type Hash []byte
// this will NOT work
type ModelTyped struct {
Bytes Hash
}
func main() {
// Migrate database
// Both tables will have a column `bytes` of type `longblob default:NULL`
if err := gormDB.AutoMigrate(&ModelRaw{}, &ModelTyped{}); err != nil {
panic(err)
}
// this works
mdl1 := &ModelRaw{Bytes: []byte("random-bytes")}
if err := gormDB.Debug().Create(mdl1).Error; err != nil {
panic(err)
}
// error here
mdl2 := &ModelTyped{Bytes: Hash("random-bytes")}
if err := gormDB.Debug().Create(mdl2).Error; err != nil {
panic(err)
}
}
上述代码会产生以下
gorm
的调试输出:2020/11/06 10:31:29 /go/src/app/main.go:47
[7.715ms] [rows:1] INSERT INTO `model_raws` (`bytes`) VALUES ('random-bytes')
2020/11/06 10:31:29 /go/src/app/main.go:53 Error 1241: Operand should contain 1 column(s)
[0.926ms] [rows:0] INSERT INTO `model_typeds` (`bytes`) VALUES ((114,97,110,100,111,109,45,98,121,116,101,115))
panic: Error 1241: Operand should contain 1 column(s)
问题演示代码库: https://github.com/Iyashi/go-gorm-bytes-test
gorm:v1
版本可以正常工作,而在gorm:v2
版本中出现了问题。
gorm
的AutoMigrate()
方法将mysql表列创建为longblob NULL
。
[]byte
转换/强制转换为string
进入mysql
都会很麻烦。对于这种情况,这样做还可以,但是应用程序未来可能会有更多的[]byte
,并且在gorm:v1
中它运行良好,因此我认为有更好的解决方案。如果没有帮助,我当然会这样做。 - IyashiPasswordHash
类型实现为string
并且它可以工作,但下一个[]byte
将再次失败,这是不可接受的。 - IyashiHash
类型实现Scanner
和Valuer
接口。示例:https://gorm.io/docs/data_types.html#Scanner-Valuer - Emin Laletovic