2

Voici mes modèles:Comment interroger un modèle de relation many to many? - Google App Engine

class User(db.Model): 
    id = db.StringProperty(required=True) 
    created = db.DateTimeProperty(auto_now_add=True) 
    updated = db.DateTimeProperty(auto_now=True) 
    name = db.StringProperty(required=True) 
    email = db.StringProperty() 

class Page(db.Model): 
    id = db.StringProperty(required=True) 
    created = db.DateTimeProperty(auto_now_add=True) 
    updated = db.DateTimeProperty(auto_now=True) 
    name = db.StringProperty(required=True) 
    link = db.StringProperty(required=True) 

class UserPage(db.Model): 
    user = db.ReferenceProperty(User, collection_name='pages') 
    page = db.ReferenceProperty(Page, collection_name='users') 

Comment puis-je construire une requête pour trouver une pages des utilisateurs?

J'ai trouvé un article qui décrit une méthode pour le faire mais est-ce le meilleur moyen? http://blog.arbingersys.com/2008/04/google-app-engine-better-many-to-many.html

Répondre

3

Votre réponse fonctionnera, mais il effectuera 7 appels à la datastore:

  • 1 pour l'appel à l'utilisateur. get_by_key_name()
  • 1 pour l'appel à UserPage ... fetch()
  • 5 pour chaque déréférencement de x.page.id intérieur de la boucle

Une autre approche qui ne fait que 3 appels à la datastore serait quelque chose comme ceci:

myuser = User.get_by_key_name("1") 
up = UserPage.all().filter('user =', myuser).fetch(5) 
keys = [UserPage.page.get_value_for_datastore(x) for x in up] 
pages = db.get(keys) 
for p in pages: 
    self.response.out.write(p.id) 

Voir http://blog.notdot.net/2010/01/ReferenceProperty-prefetching-in-App-Engine pour plus de détails.

+0

oh very nice! Je n'étais pas au courant de la boucle étant si cher. Thx pour la tête haute. – johnnytee

1

Après quelques essais, il semble que je peux utiliser:

myuser = User.get_by_key_name("1") 
up = UserPage.all().filter('user =', myuser).fetch(5) 
for x in up: 
    self.response.out.write(x.page.id) 
1

Je recommande une approche différente, qui est moins relation « relationnelle axée sur » que votre UserPage:

class User(db.Model): 
    id = db.StringProperty(required=True) 
    created = db.DateTimeProperty(auto_now_add=True) 
    updated = db.DateTimeProperty(auto_now=True) 
    name = db.StringProperty(required=True) 
    email = db.StringProperty() 

class Page(db.Model): 
    id = db.StringProperty(required=True) 
    created = db.DateTimeProperty(auto_now_add=True) 
    updated = db.DateTimeProperty(auto_now=True) 
    name = db.StringProperty(required=True) 
    link = db.StringProperty(required=True) 

    # Users linking to this page 
    users = db.ListProperty(db.Key) 

Et vous pouvez obtenir toutes les pages d'un utilisateur spécifique avec la requête suivante:

Page.gql("WHERE users = :1", user.key()) 

Veuillez noter que vous devez placer la propriété list des clés du côté où vous attendez moins d'éléments. J'ai supposé que vous auriez moins d'utilisateurs aimés à une page, que les pages liées à un utilisateur, donc je l'ai mis sur le côté Page, mais cela dépendra de votre cas d'utilisation spécifique.

Voir ici les recommandations officielles sur le nombre à plusieurs sujet: http://code.google.com/appengine/articles/modeling.html

+0

Thx pour cette approche et pour l'article. Je vais faire quelques tests avec ça. – johnnytee

+0

Merci encore pour cela, j'ai fini par aller avec cette approche. – johnnytee