When trying to get a structure with string and uint32 types through a gRPC request, it is all shifted into one key

huangapple go评论175阅读模式
英文:

When trying to get a structure with string and uint32 types through a gRPC request, it is all shifted into one key

问题

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"`
}

The 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\"8Роман Светы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 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{})

答案1

得分: 0

抱歉,我是个愚蠢的人,忘记在失眠中将file.proto更改为新的file.proto,因此函数的意外行为发生了。

英文:

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
When trying to get a structure with string and uint32 types through a gRPC request, it is all shifted into one key

huangapple
  • 本文由 发表于 2023年8月10日 22:10:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76876529.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定