У меня есть 2 хранилища данных:

class User(db.Model):
    name = db.StringProperty(required = True)
    password = db.StringProperty(required = True)
    email = db.EmailProperty(required = True)
    created = db.DateTimeProperty(auto_now_add = True)
    image = db.LinkProperty(required = True)

class Post(db.Model):
    post = db.StringProperty(required = True, multiline = True)
    submitter = db.IntegerProperty(required = True)
    receiver = db.IntegerProperty(required = True)
    created = db.DateTimeProperty(auto_now_add = True)

Однако проблема в том, что тогда я создаю страницу пользователя, где я показываю все сообщения, полученные пользователем, но я делаю это очень наивно и наивно, например, так:

ret = []
    #Get all Posts
    for p in self.getPosts():
        #If the receiver of the post is equal to uId
        if str(p.receiver) == str(uId):

            #Get submitter Details
            sDetails = self.getUserDetails(p.submitter)

            #Check that details were received
            if sDetails:
                #Add needed Details to post
                p.sName = sDetails.name
                p.sId = str(sDetails.key().id())
                p.sImage = sDetails.image

                ret.append(p)
    return ret

Как бы вы, ребята, это улучшили? В этом подходе я больше всего ненавижу необходимость просматривать каждый пост, что приведет к тому, что система будет работать очень медленно, когда система станет больше.

Также обратите внимание, что все сообщения хранятся в кэше памяти, поэтому я не могу использовать GQL, чтобы сделать это лучше. Если у вас нет лучшей идеи для хранения вещей в кэше памяти, чем мой подход ... То есть, забросить туда все часто используемые запросы и обновить кеш после добавления нового элемента в хранилище данных.

Для тех, кто, возможно, немного следит за моими вопросами, этот проект является новой концепцией для социальных сетей и опубликует ссылку, как только он будет готов :)

1
Dylan Grech 20 Мар 2013 в 23:38

1 ответ

Лучший ответ

Вам не нужно каждый раз получать все сообщения из базы данных; используйте запрос фильтра, чтобы получить все сообщения, соответствующие определенному идентификатору пользователя:

q = db.Query(Post)
q.filter('receiver =', uId)

Если вы не можете сделать это в настоящий момент, потому что вы храните каждое сообщение под одним ключом кэша памяти, возможно, вам следует изменить свой подход - он, вероятно, не будет хорошо масштабироваться. Используя запрос, подобный приведенному выше, вы можете воспользоваться функциями индексирования и запросов хранилища данных GAE, которые всегда будут превосходить по производительности прямую итерацию по всему набору сущностей в вашем приложении.

Я бы посоветовал сохранять пользовательские страницы в кэше памяти после создания их из хранилища данных.

Кроме того, на Post вы можете использовать db.ReferenceProperty для submitter и receiver:

class Post(db.Model):
post = db.StringProperty(required = True, multiline = True)
submitter = db.ReferenceProperty(reference_class=User, required = True)
receiver = db.ReferenceProperty(reference_class=User, required = True)
created = db.DateTimeProperty(auto_now_add = True)

https://developers.google.com/appengine/docs/python/datastore/typesandpropertyclasses#ReferenceProperty

2
Matthew H 21 Мар 2013 в 00:12
Хм интересно. Мне очень нравится такой подход! Единственное, в чем я немного сомневаюсь, это; При создании нового сообщения, какие данные я должен поместить в referenceProperty? Просто int с идентификатором пользователя или весь пользовательский объект?
 – 
Dylan Grech
21 Мар 2013 в 00:07
Весь пользовательский объект.
 – 
Matthew H
21 Мар 2013 в 00:10