GCP Proto数据存储区在base64中编码JsonProperty

时间:2018-02-06 14:12:52

标签: json python-2.7 google-app-engine datastore endpoints-proto-datastore

我使用"dependencies": { "@angular/animations": "^5.1.1", "@angular/cdk": "5.0.0-rc.3", "@angular/common": "^5.1.1", "@angular/compiler": "^5.1.1", "@angular/core": "^5.1.1", "@angular/forms": "^5.1.1", "@angular/http": "^5.1.1", "@angular/material": "5.0.0-rc.3", "@angular/platform-browser": "^5.1.1", "@angular/platform-browser-dynamic": "^5.1.1", "@angular/router": "^5.1.1", "core-js": "^2.4.1", "rxjs": "^5.5.5", "zone.js": "^0.8.14" }, "devDependencies": { "@angular/cli": "^1.6.7", "@angular/compiler-cli": "^5.2.0", "@angular/language-service": "^5.2.0", "@types/jasmine": "~2.8.3", "@types/jasminewd2": "~2.0.2", "@types/node": "~6.0.60", "codelyzer": "^4.0.1", "jasmine-core": "~2.8.0", "jasmine-spec-reporter": "~4.2.1", "karma": "~2.0.0", "karma-chrome-launcher": "~2.2.0", "karma-coverage-istanbul-reporter": "^1.2.1", "karma-jasmine": "~1.1.0", "karma-jasmine-html-reporter": "^0.2.2", "protractor": "~5.1.2", "ts-node": "~4.1.0", "tslint": "~5.9.1", "typescript": "~2.5.3" } 在数据存储区中存储了一个Json blob。 我不知道json数据的结构。

我正在使用<md-input-container class="md-block" flex> <label>Label</label> <input type="number" name="number" ng-model="number" min="0" max="10" required> <div ng-messages="form.number.$error" md-auto-hide="false"> <!-- mdAutoHide --> <div ng-message="required">This is required</div> <div ng-message="min">Min is 0</div> <div ng-message="max">Max is 10</div> </div> </md-input-container> 来检索我的数据。

问题是json属性是用base64编码的,我想要一个普通的json对象。

例如,json数据将是:

JsonProperty

我的代码类似于:

endpoints proto datastore

当我打电话给api获取模型时,我得到:

{
    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]) POST /_ah/api/myapi/v1/mymodel2 { "data": "eyJzZWNvbmQiOiAyLCAiZmlyc3QiOiAxfQ==" }

的base64编码

打印声明给我:eyJzZWNvbmQiOiAyLCAiZmlyc3QiOiAxfQ==

因此,在该方法中,我可以将json blob数据作为python {"second": 2, "first": 1}进行探索。 但是,在api调用中,数据以base64编码。

我花了api电话给我:

{u'second': 2, u'first': 1}

我怎样才能得到这个结果?

1 个答案:

答案 0 :(得分:1)

在您的问题评论中讨论之后,让我与您分享一个示例代码,您可以使用该代码将数据存储中的JSON对象存储(它将作为字符串存储),然后在此处检索它一种方式:

  • API调用后将显示为纯JSON。
  • 您将能够使用eval再次将其解析为Python dict。

我希望我能正确理解你的问题,这对你有帮助。

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和端点和数据存储区的生产中它应该是相同的。

在查询第一个端点之后,它将创建一个新的实体,您可以在数据存储区中找到该实体,其中包含一个属性column3,其中包含您的JSON数据字符串格式:

enter image description here

然后,如果您使用该实体的ID来检索它,那么在您的浏览器中它将显示没有任何奇怪编码的字符串,只是简单的JSON:

enter image description here

在控制台中,您将能够看到此字符串可以转换为Python字典(或者如果您愿意,也可以使用json模块转换为JSON:)

enter image description here

我希望我没有错过任何你想要实现的目标,但我认为这个代码涵盖了所有最重要的要点:属性是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, StackOverflow 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

通过这些更改,对端点的调用响应如下:

enter image description here

现在column4本身就是一个JSON对象(虽然它不是在线打印的,但我认为这不应该是一个问题。

我希望这也有帮助。如果这不是你想要的确切行为,也许应该使用可用的属性类型,但我不认为有一种类型可以打印Python dict(或JSON对象)而不事先将其转换为String。