【问题标题】:Updating DataStore JSON values using endpoints (Python)使用端点更新 DataStore JSON 值 (Python)
【发布时间】:2014-06-04 02:54:37
【问题描述】:

我正在尝试使用端点来更新我的数据存储中的一些 JSON 值。我在 GAE 中有以下数据存储...

class UsersList(ndb.Model):
    UserID = ndb.StringProperty(required=True)
    ArticlesRead = ndb.JsonProperty()
    ArticlesPush = ndb.JsonProperty()

一般来说,我尝试使用 API 的方法是让该方法接收用户 ID 和读取的文章列表(文章由包含 ID 的字典和布尔字段表示用户是否喜欢这篇文章)。我的信息(以这个逻辑为中心)如下...

class UserID(messages.Message):
    id = messages.StringField(1, required=True)


class Articles(messages.Message):
    id = messages.StringField(1, required=True)
    userLiked = messages.BooleanField(2, required=True)


class UserIDAndArticles(messages.Message):
    id = messages.StringField(1, required=True)
    items = messages.MessageField(Articles, 2, repeated=True)


class ArticleList(messages.Message):
    items = messages.MessageField(Articles, 1, repeated=True)

我尝试进行此更新的 API/Endpoint 方法如下...

@endpoints.method(UserIDAndArticles, ArticleList,
                  name='user.update',
                  path='update',
                  http_method='GET')
def get_update(self, request):
    userID = request.id
    articleList = request.items
    queryResult = UsersList.query(UsersList.UserID == userID)

    currentList = []

    #This query always returns only one result back, and this for loop is the only way
    # I could figure out how to access the query results.
    for thing in queryResult:
        currentList = json.loads(thing.ArticlesRead)

    for item in articleList:
        currentList.append(item)

    for blah in queryResult:
        blah.ArticlesRead = json.dumps(currentList)
        blah.put()

    for thisThing in queryResult:
        pushList = json.loads(thisThing.ArticlesPush)

    return ArticleList(items = pushList)

这段代码有两个问题。首先是我似乎无法弄清楚(使用 localhost Google APIs Explorer)如何使用我的 UserIDAndArticles 类将文章列表发送到端点方法。是否可以将 messages.MessageField() 作为端点方法的输入?

另一个问题是我在“blah.ArticlesRead = json.dumps(currentList)”行中遇到错误。当我尝试使用一些随机输入运行此方法时,出现以下错误...

TypeError: <Articles
 id: u'hi'
 userLiked: False> is not JSON serializable

我知道我必须制作自己的 JSON 编码器来解决这个问题,但我不确定传入 request.items 的格式是什么以及我应该如何对其进行编码。

我是 GAE 和端点(以及一般这种服务器端编程)的新手,所以请多多包涵。并提前非常感谢您的帮助。

【问题讨论】:

    标签: python json google-app-engine google-cloud-datastore google-cloud-endpoints


    【解决方案1】:

    几件事:

    • http_method 绝对应该是 POST,或者更好的是 PATCH,因为您不会覆盖所有现有值,而只是修改列表,即修补。
    • 您不需要json.loadsjson.dumps,NDB 会自动为您完成。
    • 您正在混合 Endpoints 消息和 NDB 模型属性。

    这是我想出的方法体:

    # get UsersList entity and raise an exception if none found.
    uid = request.id
    userlist = UsersList.query(UsersList.UserID == uid).get()
    if userlist is None:
        raise endpoints.NotFoundException('List for user ID %s not found' % uid)
    
    # update user's read articles list, which is actually a dict.
    for item in request.items:
        userslist.ArticlesRead[item.id] = item.userLiked
    userslist.put()
    
    # assuming userlist.ArticlesPush is actually a list of article IDs.
    pushItems = [Article(id=id) for id in userlist.ArticlesPush]
    return ArticleList(items=pushItems)
    

    此外,您可能应该将此方法包装在事务中。

    【讨论】:

    • 非常感谢@alex,您的解决方案真的很有帮助。我的 ArticlesRead 和 ArticlesPost 参数实际上是字典列表(不仅仅是 ID 列表),每个字典都有两个键(一个称为 id,另一个称为 userLiked)。事后看来,这可能不是最好的设计,我最终可能会改变它。但无论如何,您的回答帮助我指出了正确的方向。在单独的说明中,我还有另外两个说明/问题。首先是是否可以在数据存储中看到 JSON 输入(可能通过 GUI)?第二个是关于 JSON...
    • 对于 NDB 所做的自动 JSON 捆绑/取消捆绑,我注意到字典输出中键的顺序会根据我是否使用 code ArticleList(items = userlist.ArticlesPush ) code 与 ArticleList(items = json.loads(userlist.ArticlePush))。由于这些键的顺序对于返回的消息对象很重要,所以我最终使用了后者。这似乎更像是一种解决方法,而不是一个干净的解决方案,但我会接受它。并且将 http_method 设置为 GET 与 POST 是一个严重的错误,我应该意识到这一点(并且仍然必须弄清楚我的 http 协议)。
    • 嘿@user3345070 不幸的是,在数据存储查看器中看不到原始 JSON,它存储为字节(可能是压缩的)。您可以做的是使用 StructuredProperty 而不是 JsonProperty。至于字典中的键顺序 - 你根本不应该依赖它。它与 Cloud Endpoints 无关。 IE。 dict 中的键根据定义是无序的。如果你想订购它必须是别的东西。例如。请参阅重复属性部分(最后一句):developers.google.com/appengine/docs/python/ndb/…
    猜你喜欢
    • 2020-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-27
    • 2016-02-02
    • 2016-12-04
    • 1970-01-01
    相关资源
    最近更新 更多