GCP Proto Datastore 在 base64 中编码 JsonProperty
GCP Proto Datastore encode JsonProperty in base64
我使用 JsonProperty
在数据存储中存储了一个 Json 的 blob。
我不知道 json 数据的结构。
我正在使用 endpoints proto datastore
来检索我的数据。
问题是 json 属性 是用 base64 编码的,我想要一个普通的 json 对象。
例如,json 数据将为:
{
first: 1,
second: 2
}
我的代码类似于:
import endpoints
from google.appengine.ext import ndb
from protorpc import remote
from endpoints_proto_datastore.ndb import EndpointsModel
class Model(EndpointsModel):
data = ndb.JsonProperty()
@endpoints.api(name='myapi', version='v1', description='My Sample API')
class DataEndpoint(remote.Service):
@Model.method(path='mymodel2', http_method='POST',
name='mymodel.insert')
def MyModelInsert(self, my_model):
my_model.data = {"first": 1, "second": 2}
my_model.put()
return my_model
@Model.method(path='mymodel/{entityKey}',
http_method='GET',
name='mymodel.get')
def getMyModel(self, model):
print(model.data)
return model
API = endpoints.api_server([DataEndpoint])
当我调用 api 获取模型时,我得到:
POST /_ah/api/myapi/v1/mymodel2
{
"data": "eyJzZWNvbmQiOiAyLCAiZmlyc3QiOiAxfQ=="
}
其中 eyJzZWNvbmQiOiAyLCAiZmlyc3QiOiAxfQ==
是 {"second": 2, "first": 1}
的 base64 编码
打印语句给我:{u'second': 2, u'first': 1}
因此,在该方法中,我可以将 json blob 数据作为 python dict
进行探索。
但是,在 api 调用中,数据以 base64 编码。
我加急了 api 电话给我:
{
'data': {
'second': 2,
'first': 1
}
}
我怎样才能得到这个结果?
在您的问题的评论中进行讨论后,让我与您分享一个示例代码,您可以使用它在 Datastore 中存储一个 JSON 对象(它将存储为一个字符串),然后以这样的方式检索它:
- 在 API 调用后将显示为普通 JSON。
- 您将能够使用
eval
. 再次将其解析为 Python 字典
希望我正确理解了您的问题,这对您有所帮助。
import endpoints
from google.appengine.ext import ndb
from protorpc import remote
from endpoints_proto_datastore.ndb import EndpointsModel
class Sample(EndpointsModel):
column1 = ndb.StringProperty()
column2 = ndb.IntegerProperty()
column3 = ndb.StringProperty()
@endpoints.api(name='myapi', version='v1', description='My Sample API')
class MyApi(remote.Service):
# URL: .../_ah/api/myapi/v1/mymodel - POSTS A NEW ENTITY
@Sample.method(path='mymodel', http_method='GET', name='Sample.insert')
def MyModelInsert(self, my_model):
dict={'first':1, 'second':2}
dict_str=str(dict)
my_model.column1="Year"
my_model.column2=2018
my_model.column3=dict_str
my_model.put()
return my_model
# URL: .../_ah/api/myapi/v1/mymodel/{ID} - RETRIEVES AN ENTITY BY ITS ID
@Sample.method(request_fields=('id',), path='mymodel/{id}', http_method='GET', name='Sample.get')
def MyModelGet(self, my_model):
if not my_model.from_datastore:
raise endpoints.NotFoundException('MyModel not found.')
dict=eval(my_model.column3)
print("This is the Python dict recovered from a string: {}".format(dict))
return my_model
application = endpoints.api_server([MyApi], restricted=False)
我已经使用开发服务器测试了这段代码,但在生产环境中使用带有端点和数据存储的 App Engine 应该也能正常工作。
查询第一个端点后,它将创建一个新实体,您可以在 Datastore 中找到该实体,其中包含 属性 column3
以及您的 JSON 数据字符串格式:
然后,如果您使用该实体的 ID 检索它,在您的浏览器中它将显示没有任何奇怪编码的字符串,只是普通的 JSON:
并且在控制台中,您将能够看到该字符串可以转换为 Python 字典(或者也可以是 JSON,如果您使用 json
模块更喜欢):
我希望我没有漏掉你想要实现的任何一点,但我认为所有最重要的点都包含在这段代码中:属性 是一个 JSON 对象,存储它在数据存储中,以可读格式检索它,并能够再次使用它作为 JSON/dict.
更新:
我认为您应该自己看看 list of available Property Types,以便找到更符合您要求的那个。但是,作为附加说明,我通过对代码添加以下修改,对 StructuredProperty
(另一个 属性 中的 属性)进行了快速测试:
#Define the nested model (your JSON object)
class Structured(EndpointsModel):
first = ndb.IntegerProperty()
second = ndb.IntegerProperty()
#Here I added a new property for simplicity; remember, Whosebug does not write code for you :)
class Sample(EndpointsModel):
column1 = ndb.StringProperty()
column2 = ndb.IntegerProperty()
column3 = ndb.StringProperty()
column4 = ndb.StructuredProperty(Structured)
#Modify this endpoint definition to add a new property
@Sample.method(request_fields=('id',), path='mymodel/{id}', http_method='GET', name='Sample.get')
def MyModelGet(self, my_model):
if not my_model.from_datastore:
raise endpoints.NotFoundException('MyModel not found.')
#Add the new nested property here
dict=eval(my_model.column3)
my_model.column4=dict
print(json.dumps(my_model.column3))
print("This is the Python dict recovered from a string: {}".format(dict))
return my_model
进行这些更改后,对端点的调用响应如下所示:
现在 column4
是一个 JSON 对象本身(虽然它没有被打印出来 in-line,我认为这应该不是问题。
我希望这也能有所帮助。如果这不是您想要的确切行为,也许应该使用可用的 属性 类型,但我认为没有一种类型可以打印 Python 字典(或 JSON object) 而不是事先将其转换为 String.
我使用 JsonProperty
在数据存储中存储了一个 Json 的 blob。
我不知道 json 数据的结构。
我正在使用 endpoints proto datastore
来检索我的数据。
问题是 json 属性 是用 base64 编码的,我想要一个普通的 json 对象。
例如,json 数据将为:
{
first: 1,
second: 2
}
我的代码类似于:
import endpoints
from google.appengine.ext import ndb
from protorpc import remote
from endpoints_proto_datastore.ndb import EndpointsModel
class Model(EndpointsModel):
data = ndb.JsonProperty()
@endpoints.api(name='myapi', version='v1', description='My Sample API')
class DataEndpoint(remote.Service):
@Model.method(path='mymodel2', http_method='POST',
name='mymodel.insert')
def MyModelInsert(self, my_model):
my_model.data = {"first": 1, "second": 2}
my_model.put()
return my_model
@Model.method(path='mymodel/{entityKey}',
http_method='GET',
name='mymodel.get')
def getMyModel(self, model):
print(model.data)
return model
API = endpoints.api_server([DataEndpoint])
当我调用 api 获取模型时,我得到:
POST /_ah/api/myapi/v1/mymodel2
{
"data": "eyJzZWNvbmQiOiAyLCAiZmlyc3QiOiAxfQ=="
}
其中 eyJzZWNvbmQiOiAyLCAiZmlyc3QiOiAxfQ==
是 {"second": 2, "first": 1}
打印语句给我:{u'second': 2, u'first': 1}
因此,在该方法中,我可以将 json blob 数据作为 python dict
进行探索。
但是,在 api 调用中,数据以 base64 编码。
我加急了 api 电话给我:
{
'data': {
'second': 2,
'first': 1
}
}
我怎样才能得到这个结果?
在您的问题的评论中进行讨论后,让我与您分享一个示例代码,您可以使用它在 Datastore 中存储一个 JSON 对象(它将存储为一个字符串),然后以这样的方式检索它:
- 在 API 调用后将显示为普通 JSON。
- 您将能够使用
eval
. 再次将其解析为 Python 字典
希望我正确理解了您的问题,这对您有所帮助。
import endpoints
from google.appengine.ext import ndb
from protorpc import remote
from endpoints_proto_datastore.ndb import EndpointsModel
class Sample(EndpointsModel):
column1 = ndb.StringProperty()
column2 = ndb.IntegerProperty()
column3 = ndb.StringProperty()
@endpoints.api(name='myapi', version='v1', description='My Sample API')
class MyApi(remote.Service):
# URL: .../_ah/api/myapi/v1/mymodel - POSTS A NEW ENTITY
@Sample.method(path='mymodel', http_method='GET', name='Sample.insert')
def MyModelInsert(self, my_model):
dict={'first':1, 'second':2}
dict_str=str(dict)
my_model.column1="Year"
my_model.column2=2018
my_model.column3=dict_str
my_model.put()
return my_model
# URL: .../_ah/api/myapi/v1/mymodel/{ID} - RETRIEVES AN ENTITY BY ITS ID
@Sample.method(request_fields=('id',), path='mymodel/{id}', http_method='GET', name='Sample.get')
def MyModelGet(self, my_model):
if not my_model.from_datastore:
raise endpoints.NotFoundException('MyModel not found.')
dict=eval(my_model.column3)
print("This is the Python dict recovered from a string: {}".format(dict))
return my_model
application = endpoints.api_server([MyApi], restricted=False)
我已经使用开发服务器测试了这段代码,但在生产环境中使用带有端点和数据存储的 App Engine 应该也能正常工作。
查询第一个端点后,它将创建一个新实体,您可以在 Datastore 中找到该实体,其中包含 属性 column3
以及您的 JSON 数据字符串格式:
然后,如果您使用该实体的 ID 检索它,在您的浏览器中它将显示没有任何奇怪编码的字符串,只是普通的 JSON:
并且在控制台中,您将能够看到该字符串可以转换为 Python 字典(或者也可以是 JSON,如果您使用 json
模块更喜欢):
我希望我没有漏掉你想要实现的任何一点,但我认为所有最重要的点都包含在这段代码中:属性 是一个 JSON 对象,存储它在数据存储中,以可读格式检索它,并能够再次使用它作为 JSON/dict.
更新:
我认为您应该自己看看 list of available Property Types,以便找到更符合您要求的那个。但是,作为附加说明,我通过对代码添加以下修改,对 StructuredProperty
(另一个 属性 中的 属性)进行了快速测试:
#Define the nested model (your JSON object)
class Structured(EndpointsModel):
first = ndb.IntegerProperty()
second = ndb.IntegerProperty()
#Here I added a new property for simplicity; remember, Whosebug does not write code for you :)
class Sample(EndpointsModel):
column1 = ndb.StringProperty()
column2 = ndb.IntegerProperty()
column3 = ndb.StringProperty()
column4 = ndb.StructuredProperty(Structured)
#Modify this endpoint definition to add a new property
@Sample.method(request_fields=('id',), path='mymodel/{id}', http_method='GET', name='Sample.get')
def MyModelGet(self, my_model):
if not my_model.from_datastore:
raise endpoints.NotFoundException('MyModel not found.')
#Add the new nested property here
dict=eval(my_model.column3)
my_model.column4=dict
print(json.dumps(my_model.column3))
print("This is the Python dict recovered from a string: {}".format(dict))
return my_model
进行这些更改后,对端点的调用响应如下所示:
现在 column4
是一个 JSON 对象本身(虽然它没有被打印出来 in-line,我认为这应该不是问题。
我希望这也能有所帮助。如果这不是您想要的确切行为,也许应该使用可用的 属性 类型,但我认为没有一种类型可以打印 Python 字典(或 JSON object) 而不是事先将其转换为 String.