Используя Google App Engine (python SDK), я создал собственный JSONProperty () в качестве подкласса db.TextProperty (). Моя цель - хранить на лету в виде JSON информацию о питоне и легко ее извлекать. Я следовал различным примерам, найденным через Google, и настроить собственный класс и методы Property довольно просто.
Однако некоторые из моих значений dict (строк) кодируются в utf-8. При сохранении модели в хранилище данных я получаю страшную ошибку Unicode (для текстового свойства хранилища данных по умолчанию используется кодировка ASCII). Подклассы db.BlobProperty не решили проблему.
По сути, мой код выполняет следующие действия: сохраняет сущности ресурсов в хранилище данных (с URL-адресами в качестве StringProperty и полезными нагрузками POST / GET, хранящимися в dict как JSONProperty), извлекает их позже (код не включен). Я решил не использовать pickle для хранения полезных нагрузок, потому что я фанат JSON и не могу хранить объекты.
Пользовательский JSONProperty:
class JSONProperty(db.TextProperty):
def get_value_for_datastore(self, model_instance):
value = super(JSONProperty, self).get_value_for_datastore(model_instance)
return json.dumps(value)
def make_value_from_datastore(self, value):
if value is None:
return {}
if isinstance(value, basestring):
return json.loads(value)
return value
Помещение модели в хранилище данных:
res = Resource()
res.init_payloads()
res.url = "http://www.somesite.com/someform/"
res.param = { 'name': "SomeField", 'default': u"éàôfoobarç" }
res.put()
Это вызовет UnicodeDecodeError, связанную с кодировкой ASCII. Возможно, стоит отметить, что я получаю эту ошибку (каждый раз) только на производственном сервере. Я использую Python 2.5.2 на Dev.
Traceback (последний вызов был последним):
Файл "/base/data/home/apps/delpythian/1.350065314722833389/core/handlers/ResetHandler.py", строка 68, в _res_one
return res_one.put ()
Файл "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/init.py", строка 984, на месте
return datastore.Put (self._entity, config = config)
Файл "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py", строка 455, в Put
return _GetConnection (). async_put (config, entity, extra_hook) .get_result ()
Файл "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_rpc.py", строка 1219, в async_put
для pbs в pbsgen:
Файл "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_rpc.py", строка 1070, в __generate_pb_lists
pb = value_to_pb (значение)
Файл "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py", строка 239, в entity_to_pb
вернуть entity._ToPb ()
Файл "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py", строка 841, в _ToPb
properties = datastore_types.ToPropertyPb (имя, значения)
Файл "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore_types.py", строка 1672, в ToPropertyPb
pbvalue = pack_prop (name, v, pb.mutable_value ())
Файл "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore_types.py", строка 1485, в PackString
pbvalue.set_stringvalue (Юникода (значение) .encode ( 'UTF-8'))
UnicodeDecodeError: кодек «ascii» не может декодировать байт 0xc3 в позиции 32: порядковый номер не в диапазоне (128)
Мой вопрос заключается в следующем: есть ли способ создать подкласс класса db.TextProperty () и установить / применить пользовательскую кодировку? Или я что-то не так делаю? Я стараюсь избегать использования str () и придерживаюсь «Декодировать рано, везде Юникод, кодировать поздно» .
Обновление: добавлены код и трассировка стека.