我有两台服务器
>
产品服务器:通过gRPC调用处理产品CRUD操作并从用户服务器获取用户信息
type User struct {
ID string `json:"id"`
FirstName string `json:"firstName"`
MiddleName *string `json:"middleName,omitempty"`
LastName string `json:"lastName"`
Email string `json:"email"`
Disabled bool `json:"disabled"`
LastSignedInAt *time.Time `json:"lastSignedInAt,omitempty"`
Bio *string `json:"bio,omitempty"`
BirthDate *time.Time `json:"birthDate,omitempty"`
}
这里的一些字段是可选的,因为我使用的是cockroachDB(扩展postgreSQL),所以我将它们作为指针保存,以便轻松扫描变量形式的查询结果。
这是我的原始文件:
message User {
int64 id = 1;
string firstName = 2;
string lastName = 3;
string email = 5;
bool disabled = 6;
string lastSignedInAt = 8;
string bio = 9;
string birthdate = 10;
string profession = 14;
}
现在从上面的proto文件生成的模型是这样的:”
type User struct {
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
FirstName string `protobuf:"bytes,2,opt,name=firstName,proto3" json:"firstName,omitempty"`
LastName string `protobuf:"bytes,3,opt,name=lastName,proto3" json:"lastName,omitempty"`
Email string `protobuf:"bytes,4,opt,name=email,json=email,proto3" json:"email,omitempty"`
Disabled bool `protobuf:"varint,6,opt,name=disabled,proto3" json:"disabled,omitempty"`
LastSignedInAt string `protobuf:"bytes,8,opt,name=lastSignedInAt,proto3" json:"lastSignedInAt,omitempty"`
Bio string `protobuf:"bytes,9,opt,name=bio,proto3" json:"bio,omitempty"`
Birthdate string `protobuf:"bytes,10,opt,name=birthdate,proto3" json:"birthdate,omitempty"`
}
现在的问题是,当我为可选字段使用指针时,它将在没有值的情况下存储null,但在相反的站点上,gRPC不会理解空值并抛出错误。
我试过谷歌。protobuf。StringValue作为grpc类型的值,如下所示
google.protobuf.StringValue lastSignedInAt = 8;
这可以工作,但问题是我必须为处理程序中的每个字段编写条件:
if lastSignedInAt != nil {
user.LastSignedInAt = &wrappers.StringValue{Value:*lastSignedInAt}
}
解决这个问题的最佳方法是什么?我是否应该更改数据库模型或gRPC模型中的任何更改?
如果坚持使用指针,建议grpc不要使用点域
一种方法是使用反射来转换它
func ToGrpcData(in, out interface{}) error {
inVal := reflect.ValueOf(in)
if inVal.Kind() == reflect.Ptr {
inVal = inVal.Elem()
}
inTyp := inVal.Type()
outVal := reflect.ValueOf(out)
if outVal.Kind() != reflect.Ptr {
return errors.New("out data must be point value")
}
outVal = outVal.Elem()
outTyp := outVal.Type()
strWrapperType := reflect.TypeOf(wrappers.StringValue{})
// range all 'in' fields
for i := 0; i < inVal.NumField(); i++ {
fTyp := inTyp.Field(i)
fVal := inVal.Field(i)
if fTyp.Type.Kind() == reflect.Ptr {
switch fTyp.Type.Elem().Kind() {
case reflect.String: // only implement string in this test
oFTyp, ok := outTyp.FieldByName(fTyp.Name)
if ok == false {
return errors.New("not match field in out value")
}
if oFTyp.Type.Elem() != strWrapperType {
return errors.New("not match field in out value")
}
if fVal.IsNil() == false {
outVal.FieldByName(fTyp.Name).Set(
reflect.ValueOf(&wrappers.StringValue{
Value: fVal.Elem().String(),
}),
)
}
}
} else {
outVal.FieldByName(fTyp.Name).Set(fVal)
}
}
return nil
}
用法
type User struct {
Name string
Value *string
}
type ServerUser struct {
Name string
Value *wrappers.StringValue
}
usValue := "123"
u1 := User{
Name: "tom",
Value: &usValue,
}
u2 := ServerUser{}
err := ToGrpcData(&u1, &u2)
// error process ...
fmt.Println(u2)
您不能设置空值而不是您可以使用
oneof Examples {
Example1 example1 = 1;
Example2 example2 = 2;
}
当您使用其中一个时,您必须只设置一个值,您可以设置示例1或示例2,但不能同时使用这两个值。与设置nil值相比,这将解决您的问题。
方法2:
默认情况下,gRPC使所有变量都具有初始值,例如:string:“”
你也可以做的一件事不要设置nil值检查条件,如果你的值为nil,那么什么也不设置。
正如上面提到的另一个答案,如果协议缓冲区消息中的字段可以为零,那么您需要检查它们。对此你无能为力,除非有一个实用程序包可以做到这一点。
如果您希望默认值高于和超过协议缓冲区生成的默认值,则必须完全按照您注意到的那样执行并检查是否为nil。
不过,我确实有一些问题:
问题内容: 使用的技术:MySQL 5.1和PHP 5.3 我正在为我正在编写的网站设计一个新的数据库。我正在寻找现在存储纬度和经度值的最佳方法。 过去,我一直使用DECIMAL并使用PHP / MySQL选择以下形式: 查找最近的匹配地点。 开始阅读有关新技术的更多信息,我想知道是否应该使用Spatial Extensions。http://dev.mysql.com/doc/refman/5.
我的控制器中有一个断点,并且传递的模型中的所有值都为空。你知道为什么会这样吗?
问题内容: 我正在sklearn中使用模型来规范模型的功能。 现在,我想使用相同的缩放器来标准化测试集: 但我不想一直将训练数据与结合使用。有没有一种方法可以保存缩放器并稍后从其他文件中加载它? 问题答案: 所以我实际上不是这方面的专家,但是通过一些研究和一些有用的链接,我认为并将成为您的朋友。 该软件包使您可以将模型或“转储”模型保存到文件中。 我认为此链接也有帮助。它讨论了创建持久性模型。您将
我是JPA和Spring的初学者。这也是我的第一个问题。所以,为我的错误道歉。我正在练习以简单的场景作为开始。我有两个实体作为产品和类别,具有双向多对一/一对多关联。 类别类: 产品类别: CategoryRepository和ProductRepository都是从JpaRepository实现的。很少有带有@Query注释的方法签名。 使用@autowmed存储库的服务。没有任何商业逻辑。 类
问题内容: 是否可以在Scrapy管道中访问django模型,以便将已抓取的数据直接保存到模型中? 我已经看到了,但是我真的不知道如何设置它吗? 问题答案: 如果还有其他人遇到相同的问题,这就是我解决的方法。 我将其添加到我的scrapy settings.py文件中: 注意:上面的路径是到你的django项目文件夹,而不是settings.py文件。 现在,你将可以在scrapy项目中完全访问d
我有一个问题,为我的路线创建一个驱动程序。由于某些原因,它不识别属性。 这是我的路线代码: 这是我的控制器的代码: 当我使用传统函数时也会发生同样的情况,这些函数不是箭头函数。 另一方面,这是我的express配置,其中配置的路由为: 我得到这个错误: E:\elArchivero\api\控制器\index.js: 6res.send("sended");^ 类型错误:无法读取对象处未定义的属性