2010-01-08 6 views
2

en théorie, je veux avoir 100.000 personnes dans mon modèle d'utilisateur:Google App Engine GQL requête question

Je voudrais mettre en œuvre une propriété d'ID qui incrémente à chaque nouvelle entité mise.

Le but est que je puisse faire des requêtes comme "obtenir un utilisateur avec des ID de 200 à 300". Un peu comme séparer les 10000 entités en 1000 pages lisibles de 100 entités chacune.

J'ai entendu dire que la propriété ID d'App Engine ne garantit pas qu'elle augmente de manière incrémentielle.

Alors, comment puis-je implémenter mon propre identifiant d'incrémentation?

Une de mes idées est d'utiliser memcache. Ajoutez un compteur dans memcache qui augmente chaque fois qu'une nouvelle entité est insérée.

class User(db.Model): 
    nickname = db.StringProperty() 
    my_id = db.IntegerProperty() 


# Steps to add a new user entity: 
# Step 1: check memcache 
counter = memcache.get("global_counter") 

# Step 2: increment counter 
counter = counter + 1 

# Step 3: add user entity 
User(nickname="tommy",my_id=counter).put() 

# Step 4: replace incremented counter 
memcache.replace(key="global_counter",value=counter) 

# todo: create a cron job which periodically takes the memcached global_counter and 
# store it into the datastore as a backup (in case memcache gets flushed) 

Qu'en pensez-vous?

question supplémentaire: si 10 utilisateurs s'enregistrent en même temps, va-t-il gâcher le compteur memcache?

+2

Pourquoi avez-vous besoin que les identifiants soient séquentiels? Comment allez-vous gérer les utilisateurs souhaitant voir leurs comptes supprimés? Cela ne gâchera-t-il pas votre pagination? –

+0

thx pour l'entrée – fooyee

Répondre

0

Le compteur memcache peut disparaître.

Les compteurs sont difficiles à faire dans un système distribué. Il est souvent plus facile de repenser l'application pour qu'elle puisse s'en passer.

Pourquoi ne pas utiliser un horodatage à la place? Vous pouvez trier par (et page) sur cela aussi, il va générer le même ordre qu'un compteur.

+0

avec horodatage, comment puis-je faire une requête gql pour dire: numéro d'utilisateur 200 à numéro d'utilisateur 300? encore un peu floue pour moi. – fooyee

+0

ordre par horodatage + pagination (entrées 200 ~ 300) – Thilo

+0

Je comprends la commande par timestamp partie, mais la deuxième partie est encore un flou. pourriez-vous fournir un extrait de code? thx – fooyee

4

Vous n'avez pas besoin de mettre en œuvre votre propre compteur auto-incrémentée pour obtenir la mise en page que vous cherchez - regardez « Paging without a property »

En bref, le key est garanti d'être retourné dans un ordre déterministe et vous pouvez utiliser des opérateurs d'inégalité (>=, <=) pour renvoyer des résultats à partir d'une clé particulière.

Pour vos premières centaines d'utilisateurs:

users = User.all().order("__key__").fetch(101) 

Les 100 premiers résultats sont ce que vous itérer sur; le 101ème résultat, s'il est renvoyé, est utilisé comme signet dans la requête suivante - ajoutez simplement un .filter('__key__ >=', bookmark) à la requête ci-dessus, et vous obtiendrez des résultats 200-301