Sono in corso di migrazione da db.Model
a ndb.Model
. L'unico problema che devo risolvere prima di completare questa migrazione è che non esiste un metodo Model.is_saved
. Ho usato db.Model.is_saved
nella mia applicazione per determinare se i contatori sharded devono essere aggiornati su put
/delete
, per verificare la presenza di chiavi in conflitto sulla creazione di entità eccÈ possibile determinare con NDB se il modello è persistente nel datastore o no?
La documentazione dice che ndb.Model
non ha equivalenti per is_saved
metodo. Posso reimplementare alcuni casi d'uso con get_or_insert
anziché is_saved
. Ma non tutti loro.
Come un trucco sporco posso impostare il flag come _in_memory_instance
per ogni istanza che ho creato chiamando il costruttore. Ma non risolve il mio problema. Devo ancora aggiornare questo flag almeno dopo ogni chiamata put()
.
La domanda è: c'è un modo migliore per determinare se il modello è persistente nel datastore o no senza hit di datastore extra?
Modifica 1: dimenticato di menzionare: tutte le entità hanno le chiavi quindi controllare per Model._has_complete_key()
non funziona per me.
Modifica 2: dopo questa discussione https://groups.google.com/d/topic/google-appengine/Tm8NDWIvc70/discussion sembra essere l'unico modo per risolvere il mio problema è utilizzare _post_get_hook
/_post_put_hook
. Mi chiedo perché una cosa così banale non sia stata inclusa nell'API ufficiale.
Modifica 3: ho finito con la prossima classe di base per tutti i miei modelli. Ora posso lasciare la mia base di codice (quasi) intatta:
class BaseModel(ndb.Model):
@classmethod
def _post_get_hook(cls, key, future):
self = future.get_result()
if self:
self._is_saved = bool(key)
def _post_put_hook(self, future):
self._is_saved = future.state == future.FINISHING
def is_saved(self):
if self._has_complete_key():
return getattr(self, "_is_saved", False)
return False
puoi verificare se l'oggetto ha effettivamente una chiave/id? (eventualmente in una clausola try/except). Non ho familiarità con la classe del modello NDB, ma ricordo che db.Model genera un errore (o restituisce None?) se si tenta di ottenere l'id/chiave di un'istanza del modello prima che venga salvata (o possibilmente restituisca "None"). Non pensare che finirebbe con un successo di Datastore. Se funziona, puoi semplicemente scrivere una proprietà che è qualcosa come 'def is_saved (self): return self.key() è None' (o farlo con una clausola try/except che restituisce True se viene sollevata un'eccezione e False altrimenti). –
Il controllo della chiave non funzionerà se si crea una chiave. Una possibile alternativa (ma potrebbe essere insufficiente) è un flag creation_date (impostato su auto_now_add = True). Dalla documentazione "Il valore automatico non viene generato finché l'entità non viene scritta, ovvero, queste opzioni non forniscono valori predefiniti dinamici." Tuttavia se la scrittura fallisce, quel valore verrà impostato. Anche se dovresti sapere che la scrittura è fallita ;-) –
usa alternativamente un _post_put_hook per impostare il tuo flag che indica che è stato salvato. –