首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有长对象列表作为字段w/endpoints proto-数据存储的

问具有长对象列表作为字段w/endpoints proto-数据存储的
EN

Stack Overflow用户
提问于 2014-10-26 18:00:34
回答 2查看 202关注 0票数 1

我要建立一个Club模型,它的members类型是User。很明显,一个俱乐部可以有大量的会员。

我做过这个

代码语言:javascript
复制
class User(EndpointsModel):
    username = ndb.StringProperty(required=True)


class Club(EndpointsModel):
    ....
    members_key = ndb.KeyProperty(kind="User", repeated=True)

    @EndpointsAliasProperty(repeated=True,property_type=User.ProtoModel())
    def members(self):
        return ndb.get_multi(self.members_key)

在响应中这样做,我得到了的整个用户列表,在这种情况下,我有5000个成员可能需要一段时间。

是否有可能将此列表分页?也许用ProtoCollection()代替ProtoModel()?(我尝试了,但没有成功)。

或者,如何创建一个/club/{id}/members类型的端点来返回成员的列表(分页)?

EN

回答 2

Stack Overflow用户

发布于 2014-10-27 07:38:55

在这里,我做了一些测试,我找到了这个解决方案(在club/{id}/members上有这个方法)

我为标准端点创建了一个资源容器。这些消息复制query_method作为输入的内容。

代码语言:javascript
复制
ID_RESOURCE_PAGE = endpoints.ResourceContainer(
    message_types.VoidMessage,
    id=messages.IntegerField(1, variant=messages.Variant.INT64),
    cursor=messages.StringField(2, variant=messages.Variant.STRING, required=False, default="1"),
    limit=messages.IntegerField(3, variant=messages.Variant.INT32, required=False, default=10)
)

然后我创建了一个像这样的标准@endopint.method

代码语言:javascript
复制
@endpoints.method(ID_RESOURCE_PAGE, User.ProtoCollection(),
                      path='club/{id}/members',
                      http_method='GET',
                      name='club.members')
    def club_memebers(self, request):
        # check if user has ownership
        club = Club.get_by_id(request.id)
        page_size = request.limit
        # convert the cursors, usually it's a token, here is page number.
        page = int(request.cursor)
        # internal check, just in case.
        if (page is None or page < 0):
            raise endpoints.BadRequestException(message="Page field must be a positive integer")
        if (page_size is None or page_size < 0 or page > 100):
            raise endpoints.BadRequestException(
                message="Page_size field must be a positive integer and cannot be greater than 100")
        # compute start and end users to retrive
        start = (page - 1) * page_size
        end = page * page_size
        # crop the list
        res_list = club.membersUser[start:end]
        # create the object
        ret = User.ToMessageCollection(res_list)
        # it's probably another page
        if (len(res_list) == page_size):
            # add next page as nextPageToken, not the best but the easy way
            ret.nextPageToken = str(page + 1)
        return ret

请注意,我使用User.ProtoCollection()自动序列化了集合,并将页面号伪造为ret.nextPageToken。最后一次编辑看起来不太干净(实际上也不是),但是查询有效。

不过,我对这个解决方案并不满意。

票数 1
EN

Stack Overflow用户

发布于 2014-12-13 23:35:32

还有很多其他方法可以实现多用户对一个俱乐部的关系--我想在用户中存储一个“俱乐部”重复属性,该属性引用他们所属的俱乐部(存储俱乐部的密钥)。查询满足clubs属性的用户,并将结果限制在页面大小。使用类似的模式

next_page_results = User.all().filter('club =', club_key).filter('__key__ >', last_seen_key).order('key').run(limit=page_size)

确保正确检索页面,在正确的位置开始和停止。

(下一次调用的last_seen_key = next_page_results[-1] )

按照您所做的方式,每次获取所有结果并在内存中进行筛选。这很糟糕,而且会花你的钱。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26576158

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档