I'm trying to get a structure from a database. I use gorm and gRPC for this. Previously, I used only string data types. and there were no problems. Here is my struct that was previously for gorm:
type Book struct {
BookID string `gorm:"primarykey;autoIncrement"`
Name string
Year string
Edition string
Authors []*Author `gorm:"many2many:book_author"`
}
former struct generated by file.proto:
type Book struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Bookid string `protobuf:"bytes,1,opt,name=bookid,proto3" json:"bookid,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
Year string `protobuf:"bytes,3,opt,name=year,proto3" json:"year,omitempty"`
Edition string `protobuf:"bytes,4,opt,name=edition,proto3" json:"edition,omitempty"`
}
and a function on the server side that handles all this:
func (*server) UpdateBook(ctx context.Context, req *pb.UpdateBookRequest) (*pb.UpdateBookResponse, error) {
fmt.Println("Update Book")
var book Book
reqBook := req.GetBook()
res := DB.Model(&book).Where("book_id=?", reqBook.Bookid).Updates(
Book{Name: reqBook.Name, Year: reqBook.Year, Edition: reqBook.Edition})
if res.RowsAffected == 0 {
return nil, errors.New("Books not found")
}
return &pb.UpdateBookResponse{
Book: &pb.Book{
Bookid: book.BookID,
Name: book.Name,
Year: book.Year,
Edition: book.Edition,
},
}, nil
}
as a result, when sending a gRPC request to getBooks(), I got what I needed:
{
"books": [
{
"bookid": "",
"name": "Логические ошибки",
"year": "2017",
"edition": "1"
},
{
"bookid": "",
"name": "LINUX API исчерпывающее руководство",
"year": "2017",
"edition": "1"
},
{
"bookid": "",
"name": "Сказки громовых",
"year": "1999",
"edition": "1"
},
{
"bookid": "",
"name": "Алгоритмы. Руководство по разработке",
"year": "2022",
"edition": "3"
},
Then, for gorm to work correctly, I needed to change the bookid data type from string to uint32, file.proto was also regenerated. Current gorm struct:
type Book struct {
BookID uint32 `gorm:"primarykey;autoIncrement"`
Name string
Year string
Edition string
Authors []*Author `gorm:"many2many:book_author"`
}
Current struct generated by file.proto:
type Book struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Bookid uint32 `protobuf:"varint,1,opt,name=bookid,proto3" json:"bookid,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
Year string `protobuf:"bytes,3,opt,name=year,proto3" json:"year,omitempty"`
Edition string `protobuf:"bytes,4,opt,name=edition,proto3" json:"edition,omitempty"`
}
But now when sending a gRPC request, I get all the values in one line of the key:
{
"books": [
{
"bookid": "",
"name": "",
"year": "",
"edition": "еские ошибки2017\"1\nH\b;LINUX API исчерпывающее руководство2017\"1\n*\bСказки громовых1999\"1\nQ\bDАлгоритмы. Руководство по разработке2022\"3\n\"\bРоман Светы2003\"1"
}
]
}
The reason for this behavior of the function is not clear to me, and if you send everything in json format, then the result comes correct (client-side code is written for json)
I tried to bring everything back, but because of this, gorm did not work properly
I would like to get the same desired result as before, but at the same time do not change data types, because correct operation depends on them gorm, but it seems my knowledge is not enough
I also tried to configure the encoding of gorm for correct operation
dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
dbUser,
password,
host,
port,
dbName,
)
DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
DB.AutoMigrate(Book{})
I'm sorry, I'm a fool who forgot to change file.proto to a new file.proto in the insomnia, therefore, the unexpected behavior of the function occurred