由于cursor()方法中“ IN过滤器”的局限性,使用游标进行分页查询会导致错误……该怎么办?

发布于 2021-01-29 15:00:39

我正在通过使用以下模型开发类似微博系统的Twitter:

class Member(db.Model):    
    user = db.UserProperty(required=True)
    follower_count = db.IntegerProperty(default=0) # members following you    
    following_count = db.IntegerProperty(default=0) # members you are following

class NewsItem(db.Model):    
    text = db.StringProperty(required=True)
    posted_by = db.ReferenceProperty(reference_class=Member,required=True,collection_name="posted_items")
    posted_on = db.DateTimeProperty(auto_now_add=True)
    status = db.IntegerProperty(default=1) # 0: deleted

class Follow(db.Model):    
    member = db.ReferenceProperty(reference_class=Member,required=True,collection_name="followings")    
    followed_member = db.ReferenceProperty(reference_class=Member,required=True,collection_name="followers")    
    added_on = db.DateTimeProperty(auto_now_add=True)

在此模型结构中,我使用以下代码检索当前用户遵循的成员的消息:

follow_log_list = Follow.gql('WHERE member = :1 ', member)
followed_member_list = []
for follow_log in follow_log_list:
    followed_member_list.append(follow_log.followed_member)

query = NewsItem.all()
query.filter('posted_by IN', followed_member_list)
query.filter('status =', 1)
query.order('-posted_on')
query.with_cursor(cursor)   
newsList = query.fetch(10)

template_values['cursor'] = query.cursor()

调用query.cursor()方法时,出现以下错误:

“没有游标可用于MultiQuery(使用“ IN”或“!=“运算符进行查询)”

这是正常现象,因为在游标的文档中此限制明确表示为:

http://code.google.com/appengine/docs/python/datastore/queries.html

“不能在使用IN或!=过滤运算符的查询中使用游标。”

获取关注成员职位的替代方法是什么?

谢谢,

编辑:已发布消息按其状态过滤,并按其发布日期排序…但是示例未在此处显示,我已对其进行了更改…

关注者
0
被浏览
86
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    我的解决方案是将日期值像光标一样使用,正如我描述的那样,它是对尼克森的答案的注释…就像这样:

    if cursor: # This is not actually a cursor! It is base64 datetime string
      cursordate = _strptime(base64.b64decode(cursor)) # _strptime is a local method that converts str to datetime
    
    # IN has a limit for lists: 30 items allowed
    listofNewsLists = []
    listofMemberLists = [followed_member_list[i:i+30] for i in range(0, len(followed_member_list), 30)]
    for eachList in listofMemberLists:
       query = NewsItem.all()
       query.filter('posted_by IN', eachList).filter('status =', 1)
       if cursor:
          query.filter('posted_on <', cursordate)
       query.order('-posted_on')                        
       listofNewsLists.append(query.fetch(PAGE_SIZE))
    
      newsList = []
      if listofNewsLists:
        emptyListCount = 0
        while len(newsList) < PAGE_SIZE and emptyListCount < len(listofNewsLists):
          max = datetime.datetime.min
          maxInd = -1
          emptyListCount = 0
          for i in range(len(listofNewsLists)):
            if listofNewsLists[i] == []:
              emptyListCount += 1
            elif listofNewsLists[i][0].posted_on > max:
              max = listofNewsLists[i][0].posted_on
              maxInd = i
          if max > datetime.datetime.min:
            newsList.append(listofNewsLists[maxInd].pop(0))
    
    template_values['cursor'] = base64.b64encode(newsList[-1].posted_on.isoformat())
    

    那是; 我将最后显示的项目的日期值存储为新列表的起点…

    除非我有具有相同post_on值的项目,否则这很好(我猜)。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看