db.ReferenceProperty () vs ndb.KeyProperty en App Engine

La propiedad de referencia fue muy útil para manejar las referencias entre dos módulos. Ejemplo de Fox:

class UserProf(db.Model): name = db.StringProperty(required=True) class Team(db.Model): manager_name = db.ReferenceProperty(UserProf, collection_name='teams') name = db.StringProperty(required=True) 
  • Para obtener ‘manager_name’ con la instancia de equipo, usamos team_ins.manager_name.
  • Para obtener “equipos” que son administrados por una instancia de usuario particular, usamos user_instance.teams y repetimos.

¿No parece fácil y comprensible?

Al hacer lo mismo usando NDB, tenemos que modificar

db.ReferenceProperty(UserProf, collection_name='teams') -> ndb.KeyProperty(kind=UserProf)

Como puede ver, el manejo de este tipo de escenarios parece más fácil y legible en db que en ndb.

  • ¿Cuál es la razón para eliminar ReferenceProperty en ndb?
  • Incluso la consulta user_instance.teams de db debería haber hecho lo mismo que se hace en ndb’s for loop. Pero en ndb, estamos mencionando explícitamente el uso de for loop.
  • ¿Qué está sucediendo detrás de escena cuando hacemos user_instance.teams?

Gracias por adelantado..

Tim lo explicó bien. Descubrimos que un anti-patrón común estaba usando propiedades de referencia y cargándolas una por una, porque la notación “entity.property1.property2” no deja claro que el primer punto causa una operación de “obtención” de la base de datos. Así que lo hicimos más obvio al forzarlo a escribir “entity.property1.get (). Property2”, y lo hicimos más fácil para hacer la captura previa de lotes (sin la solución compleja del blog de Nick) simplemente diciendo “entity.property1.get_async () “para un grupo de entidades: esto pone en cola una operación de obtención de un solo lote sin bloquear el resultado, y cuando haga referencia a continuación a cualquiera de estas propiedades usando” entity.property1.get (). property2 “, esto no iniciará otra. obtener operación, pero solo espera a que el lote se complete (y la segunda vez que lo haga, el lote ya está completo). También de esta manera la integración en proceso y memcache es gratuita.

No sé la respuesta de por qué Guido no implementó la propiedad de referencia.

Sin embargo, encontré que pasé mucho tiempo usando pre_fetch_refprops http://blog.notdot.net/2010/01/ReferenceProperty-prefetching-in-App-Engine (pre busca todas las propiedades de referencia agarrando todas las claves con get_value_for_datastore, ) y luego hace un get_multi en las teclas.

Esto fue mucho más eficiente.

Además, si el objeto al que se hace referencia no existe, obtendría un error al intentar recuperar el objeto.

Si decapaste un objeto que tenía referencias, terminaste decapado mucho más de lo que probablemente también planeaste.

Así que encontré, excepto en el caso de un caso, en el que tienes una entidad única y querías agarrar el objeto al que se hace referencia con el tipo de nombre de acceso, o tenías que saltar a través de todo tipo de aros para evitar que la entidad a la que se hace referencia fuera a buscarse.