Преобразование данных сериализатора django в google.protobuf.struct_pb2.Struct дает ошибку: TypeError: неверный тип аргумента для встроенной операции
Я хочу создать ответное сообщение в grpc со следующим форматом:
message Match {
int32 index = 1;
google.protobuf.Struct match = 2;
google.protobuf.Struct status = 3;
}
У меня есть сериализатор, и я хочу преобразовать данные в protobuf struct. Мой сериализатор вложенный и длинный, поэтому я разместил здесь только небольшую часть кода.
class MatchSerializer(proto_serializers.ModelProtoSerializer):
competition = serializers.SerializerMethodField()
match = serializers.SerializerMethodField()
status = serializers.SerializerMethodField()
class Meta:
model = Match
proto_class = base_pb2.Match
fields = ['index', 'match', 'competition', 'status']
def get_competition(self, obj):
data = SomeSerializer(obj.competition).data
struct_data = struct_pb2.Struct()
return struct_data.update(data)
def get_status(self, obj):
status_dict = {
0: {0: "not started"},
1: {1: "finished"},
2: {9: "live"},
}
result = status_dict[obj.status]
struct_data = struct_pb2.Struct()
return struct_data.update(result)
def get_match(self, obj):
data = SomeOtherSerializer(obj.match).data
struct_data = struct_pb2.Struct()
return struct_data.update(data)
Кроме того, я не могу найти источник того, что действительно создает эту проблему. Я получаю эту ошибку при сериализации:
Traceback (most recent call last):
File "/project/venv/lib/python3.10/site-packages/grpc/_server.py", line 555, in _call_behavior
response_or_iterator = behavior(argument, context)
File "/project/base/grpc/services.py", line 44, in GetUserSubscribedTeamsMatches
return MatchSerializer(val).message
File "/project/venv/lib/python3.10/site-packages/django_grpc_framework/proto_serializers.py", line 31, in message
self._message = self.data_to_message(self.data)
File "/project/venv/lib/python3.10/site-packages/rest_framework/serializers.py", line 555, in data
ret = super().data
File "/project/venv/lib/python3.10/site-packages/rest_framework/serializers.py", line 253, in data
self._data = self.to_representation(self.instance)
File "/project/venv/lib/python3.10/site-packages/rest_framework/serializers.py", line 522, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "/project/venv/lib/python3.10/site-packages/rest_framework/fields.py", line 1838, in to_representation
return method(value)
File "/project/base/grpc/serializers.py", line 97, in get_matches
return struct_data.update(data[0])
File "/project/venv/lib/python3.10/site-packages/google/protobuf/internal/well_known_types.py", line 522, in update
_SetStructValue(self.fields[key], value)
File "/project/venv/lib/python3.10/site-packages/google/protobuf/internal/well_known_types.py", line 448, in _SetStructValue
struct_value.struct_value.update(value)
File "/project/venv/lib/python3.10/site-packages/google/protobuf/internal/well_known_types.py", line 522, in update
_SetStructValue(self.fields[key], value)
TypeError: bad argument type for built-in operation
Я попробовал инструменты отладки в pycharm и просмотрел несколько строк, но, похоже, не могу найти проблему
В то время как, например, 0
(int
) является допустимым ключом для диктанта Python:
d = {
0: {0: "not started"},
1: {1: "finished"},
2: {9: "live"},
}
print(d)
Это не действительный Struct
ключ и не действительный JSON (объектный) ключ, который Struct
предназначен для представления:
match = Struct()
match.update(d)
Броски bad argument type for built-in operation
Вам нужно будет использовать string
значения для ключей:
map<string, Value>