2012-10-18 12 views
7

Ich möchte einen Entitätsschlüssel erhalten, der die Entitäts-ID und einen Vorgänger kennt. Die ID ist in der vom Vorgänger definierten Entitätsgruppe eindeutig. Es scheint mir, dass es nicht möglich ist, ndb-Schnittstelle zu verwenden. Wie ich Datenspeicher verstehe, kann es durch die Tatsache verursacht werden, dass diese Operation eine vollständige Indexsuche erfordert. Die von mir verwendete Problemumgehung besteht darin, eine berechnete Eigenschaft im Modell zu erstellen, die den ID-Teil des Schlüssels enthält. Ich bin jetzt in der Lage einen Vorfahren Abfrage zu tun und den Schlüsselnbb Entitätsschlüssel nach ID ohne Eltern abrufen

class SomeModel(ndb.Model): 
    ID = ndb.ComputedProperty(lambda self: self.key.id()) 

    @classmethod 
    def id_to_key(cls, identifier, ancestor): 
     return cls.query(cls.ID == identifier, 
         ancestor = ancestor.key).get(keys_only = True) 

Es scheint zu arbeiten, aber gibt es bessere Lösungen für dieses Problem?

Aktualisieren Es scheint, dass für Datenspeicher die natürliche Lösung ist, vollständige Pfade anstelle von Bezeichnern zu verwenden. Anfangs dachte ich, es wäre zu beschwerlich. Nach dem Lesen von dragonx antwort habe ich meine Bewerbung neu gestaltet. Zu meiner Überraschung sieht alles jetzt viel einfacher aus. Zusätzliche Vorteile sind, dass meine Entitäten weniger Speicherplatz benötigen und ich keine zusätzlichen Indizes benötige.

+0

Klingt wie Sie die richtige Antwort bekommen! –

+0

ID ist _nicht_ garantiert innerhalb einer Entitätsgruppe eindeutig - nur für eine bestimmte übergeordnete Entität. –

Antwort

8

Ich lief auch in dieses Problem. Ich denke du hast die Lösung.

Die bessere Lösung wäre, die Verwendung von IDs für Referenzobjekte zu beenden und entweder den tatsächlichen Schlüssel oder einen vollständigen Pfad zu speichern.

Intern verwende ich Schlüssel statt IDs.

Auf meiner Rest API habe ich http://url/kind/id (wo ID wie "123" aussah), um eine Entität zu holen. Ich habe das geändert, um der Entität den vollständigen Vorgängerpfad zu geben: http://url/kind/ancestor-ancestor-id (789-456-123), ich würde dann diese Zeichenfolge analysieren, einen Schlüssel generieren und dann per Schlüssel abrufen.

+0

Sie haben Recht. Alles ist einfacher mit dem vollständigen Vorfahrenpfad. Es scheint, dass dies der richtige Weg ist, um solche Dinge im Datenspeicher zu tun. Danke –

+0

Vergessen Sie nicht, dass es einen "Schlüssel" -Typ im Datenspeicher gibt, den Sie verwenden können, um tatsächliche Schlüssel (KeyProperty) zu speichern. –

+0

In einer Randnotiz hat Java [diese Methoden] (https://developers.google.com/appengine/docs/java/javadoc/com/google/appengine/api/datastore/KeyFactory#keyToString%28com.google.appengine .api.datastore.Key% 29) Serialisierung und Deserialisierung von Schlüsseln – aimless

3

Da Sie alle Informationen über Ihre Vorfahren haben und wissen Sie ID, können Sie direkt Ihren Schlüssel erstellen und an das Unternehmen erhalten, wie folgt:

my_key = ndb.Key(Ancestor, ancestor.key.id(), SomeModel, id) 
entity = my_key.get() 

diese Weise können Sie eine Abfrage verhindern, dass die mehr kostet als a get Betrieb sowohl in Bezug auf Geld und Geschwindigkeit.

Hoffe, das hilft.

+1

Es ist eine gute Lösung, wenn Vorfahre auch ein Elternteil ist, aber es ist nicht mein Fall –

+0

Da Sie den Begriff "Vorfahren" verwendet haben, dachte ich, Sie meinten, dass es ein Elternteil war. Wenn dies nicht der Fall ist, dann ist Ihr Ansatz der richtige. –

1

Ich möchte die Antwort von Dargonx etwas ergänzen.

In meiner Anwendung auf Front-End verwende ich Stringdarstellung des Schlüssels:

str(instance.key()) 

Wenn ich brauche ein paar Änderungen mit instence zu machen, auch wenn es ein Nachkomme ist ich nur String-Darstellung des Schlüssels verwenden. Zum Beispiel habe ich key_str - Argument von Anforderungsinstanz "zu löschen:

instance = Kind.get(key_str) 
instance.delete() 
0

Meine Lösung ist urlsafe mit Artikeln über Eltern-ID ohne Sorge zu bekommen:

pk = ndb.Key(Product, 1234) 
usafe = LocationItem.get_by_id(5678, parent=pk).key.urlsafe() 
# now can get by urlsafe 
item = ndb.Key(urlsafe=usafe) 
print item