Как извлечь данные из двух классов GQL?

У меня есть следующие 2 класса:

class UsersRSS(db.Model):
    userId = db.IntegerProperty()
    fileHash = db.StringProperty()
    added = db.DateTimeProperty(auto_now_add=True)

class Files(db.Model):
    fileHash = db.StringProperty()
    title = db.StringProperty()
    file = db.BlobProperty()
    added = db.DateTimeProperty(auto_now_add=True)    

Мне нужно создать запрос GQL, который вернет данные из обеих таблиц:

items = UsersRSS.gql("WHERE userId = :userId ORDER BY date DESC LIMIT 10", userId=user_id)

Но каждое item, кроме полей fileHash и added, должно содержать поля из второго класса - title и file (сопоставление должно производиться по полю fileHash).


person LA_    schedule 27.04.2011    source источник


Ответы (1)


Невозможно получить из хранилища данных разные виды с помощью одного и того же оператора GQL Select.

Другим вариантом может быть использование ReferenceProperty. чтобы создать отношение «многие к одному» между UsersRSS и Files, рефакторинг вашего кода следующим образом:

class UsersRSS(db.Model):
    userId = db.IntegerProperty()
    file = db.ReferenceProperty(Files)
    added = db.DateTimeProperty(auto_now_add=True)

class Files(db.Model):
    fileHash = db.StringProperty()
    title = db.StringProperty()
    file = db.BlobProperty()
    added = db.DateTimeProperty(auto_now_add=True)

items = UsersRSS.gql("WHERE userId = :userId ORDER BY date DESC LIMIT 10", userId=user_id)

Таким образом, свойства Files будут автоматически разыменованы с использованием нотации через точку item.file.title:

for item in items:
    print item.UserID
    print item.Added
    print item.file.title #This costs an additional RPC call to Datastore

Чтобы избавить свое приложение от накладных расходов RPC ReferenceProperty, ознакомьтесь с актуальной статьей Предварительная загрузка ReferenceProperty.

person systempuntoout    schedule 27.04.2011
comment
Спасибо! как добавить file к UsersRSS с таким подходом? file = Files(key_name="z"+self.request.get('hash')); file.put(); fileRecord = UsersRSS(); fileRecord.file = file; fileRecord.put() правильный подход? - person LA_; 27.04.2011
comment
правильно, вы, вероятно, забыли установить userId на fileRecord перед fileRecord.put(). - person systempuntoout; 27.04.2011