Estoy en proceso de migración de db.Model
a ndb.Model
. El único problema que tengo que resolver antes de finalizar esta migración es que no existe el método Model.is_saved
. He utilizado db.Model.is_saved
en mi solicitud para determinar si los contadores fragmentados deben actualizarse en put
/delete
, para comprobar si hay llaves en conflicto en la creación de entidades etc.¿Es posible determinar con NDB si el modelo es persistente en el almacén de datos o no?
La documentación dice que ndb.Model
no tiene equivalente para is_saved
método. Puedo volver a implementar algunos casos de uso con get_or_insert
en lugar de is_saved
. Pero no todos ellos.
Como un hack sucio puedo establecer una bandera como _in_memory_instance
para cada instancia que he creado llamando al constructor. Pero no resuelve mi problema. Todavía tengo que actualizar esta bandera al menos después de cada llamada a put()
.
La pregunta es: ¿hay una mejor manera de determinar si el modelo es persistente en el almacén de datos o no sin un hit extra del almacén de datos?
Edición 1: Se olvidó de mencionar: todas las entidades obtuvieron claves, así que verifique Model._has_complete_key()
no funciona para mí.
Editar 2: después de esta discusión https://groups.google.com/d/topic/google-appengine/Tm8NDWIvc70/discussion parece ser la única manera de resolver mi problema es utilizar _post_get_hook
/_post_put_hook
. Me pregunto por qué una cosa tan trivial no se incluyó en la API oficial.
Editar 3: Terminé con la próxima clase base para todos mis modelos. Ahora puedo salir de mi base de código (casi) sin tocar:
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
¿Puedes verificar si el objeto tiene una clave/identificación? (posiblemente en una cláusula try/except). No estoy familiarizado con la clase de modelo NDB, pero recuerdo que db.Model genera un error (o devuelve None?) si intenta obtener la id/clave de una instancia de modelo antes de que se guarde (o posiblemente devuelva 'None'). No creas que eso también terminaría con un Datastore. Si eso funciona, podrías simplemente escribir una propiedad que sea algo como 'def is_saved (self): return self.key() es None' (o hacerlo con una cláusula try/except que devuelva True si se produce una excepción y False de lo contrario) –
Verificar la clave no funcionará si está creando una clave. Una posible alternativa (pero puede ser insuficiente) es tener un indicador de fecha de creación (establecido en auto_now_add = True). From the docs "El valor automático no se genera hasta que se escribe la entidad, es decir, estas opciones no proporcionan valores predeterminados dinámicos". Sin embargo, si la escritura falla, se establecerá ese valor. Aunque deberías saber que la escritura falló ;-) –
alternativamente usa un _post_put_hook para establecer tu bandera indicando que se guardó. –