Ein Problem, das Sie haben, ist, dass User.ID
einzigartig wird nicht trivial sein. Das Problem ist, dass zwei Schreibvorgänge in der Datenbank auf verschiedenen Shards auftreten können, beide ungefähr gleichzeitig nach vorhandenen Einträgen suchen, die der Eindeutigkeitsbedingung entsprechen und keine finden, dann beide identische Einträge erstellen (in Bezug auf die eindeutige Eigenschaft) und dann Sie einen ungültigen Datenbankstatus haben. Um dieses Problem zu lösen, bietet appengine die Möglichkeit, sicherzustellen, dass bestimmte Datenspeicher-Entitäten immer auf derselben physischen Maschine platziert sind.
Dazu verwenden Sie die Entitätstasten, um Google mitzuteilen, wie die Entitäten zu organisieren sind. Nehmen wir an, Sie möchten, dass der Benutzername eindeutig ist. Ändern User
zu wie folgt aussehen:
class User(db.Model):
datejoined = db.DateTimeProperty(auto_now_add=True)
Ja, das ist es wirklich. Es gibt keinen Benutzernamen, da dieser im Schlüssel verwendet wird, sodass er nicht separat angezeigt werden muss. Wenn Sie möchten, können Sie dies tun ...
class User(db.Model):
datejoined = db.DateTimeProperty(auto_now_add=True)
@property
def name(self):
return self.key().name()
Um eine Instanz eines User
zu erstellen, müssen Sie jetzt etwas anderes zu tun, müssen Sie eine key_name
in der init-Methode angeben.
someuser = User(key_name='john_doe')
...
someuser.save()
Nun, wirklich wollen Sie sicherstellen, dass die Nutzer überschreiben einander nicht, so müssen Sie die Erstellung eines Benutzers in einer Transaktion wickeln. Zuerst eine Funktion definieren, die neccesary Prüfung tut:
def create_user(username):
checkeduser = User.get_by_key_name(username)
if checkeduser is not None:
raise db.Rollback, 'User already exists!'
newuser = User(key_name=username)
# more code
newuser.put()
Dann rufen Sie es auf diese Weise
db.run_in_transaction(create_user, 'john_doe')
einen Benutzer zu finden, haben Sie gerade diese:
someuser = User.get_by_key_name('john_doe')
Als nächstes Sie benötigen eine Möglichkeit, den Inhalt dem Benutzer zuzuordnen, und umgekehrt. Eine Lösung besteht darin, den Inhalt in dieselbe Entitätsgruppe wie den Benutzer zu stellen, indem der Benutzer als übergeordnetes Element des Inhalts deklariert wird. Um dies zu tun, die Sie nicht brauchen, um den Inhalt zu ändern überhaupt, aber Sie es ein wenig anders erstellen (ähnlich wie Sie mit User haben):
somecontent = Content(parent=User.get_by_key_name('john_doe'))
So gegeben, ein Content-Objekt, können Sie nachschlagen der Benutzer durch seinen Schlüssel Prüfung:
someuser = User.get(somecontent.key().parent())
in umgekehrter Richtung gehen, sucht alle Inhalte für einen bestimmten Benutzer auf nur ein wenig komplizierter.
allcontent = Content.gql('where ancestor is :user', user=someuser).fetch(10)
Dies ist genau das, was ich suche! –
@TokenMacGuy: Mit 'newuser.save()' meinst du 'newuser.put()'? – Kit