def contains(self, parent_instance, instance): if uses_list(self.relationship): if self.back_relation and not uses_list(self.back_relation): return self.get_attribute( instance, self.back_relation) == parent_instance return instance in self.get_attribute(parent_instance) else: return instance == self.get_attribute(parent_instance)
def decorate_query( self, query, owner_alias, coll_alias, parent_instance, ctx): # This will decorate a query with a join on the relation. inv = self.back_relation if inv: query = query.join(owner_alias, getattr(coll_alias, inv.key)) else: # hope for the best try: query = query.join(owner_alias) except InvalidRequestError: getLogger().error("Could not join %s to %s" % (owner_alias, query)) # This is very likely to fail downstream return query found_key = False if inv and not uses_list(inv): # Try to constrain on coll_alias's key vs owner_alias. # Difficult cases happen when tombstone is part of the # reln's columns for column in inv.local_columns: for fk in column.foreign_keys: if fk.column.table == parent_instance.__class__.__table__: query = query.filter( getattr(coll_alias, column.name) == parent_instance.id) found_key = True if not found_key: query = query.filter(owner_alias.id == parent_instance.id) return query
def on_new_instance(self, instance, parent_instance): if not isinstance(instance, self.collection_class): return # if the relation is through a helper class, # create that and add to assocs (TODO) # otherwise set the appropriate relationship (below.) # Prefer non-list properties because we can check if they're set. if not uses_list(self.relationship): if getattr(parent_instance, self.relationship.key, None) is None: # print "Setting1 ", parent_instance, self.relationship.key, instance setattr(parent_instance, self.relationship.key, instance) elif self.back_relation and not uses_list(self.back_relation): inv = self.back_relation if getattr(instance, inv.key, None) is None: # print "Setting2 ", instance, inv.key, parent_instance setattr(instance, inv.key, parent_instance) elif self.back_relation: inv = self.back_relation # print "Adding1 ", instance, inv.key, parent_instance getattr(instance, inv.key).append(parent_instance) else: # print "Adding2 ", parent_instance, self.relationship.key, instance getattr(parent_instance, self.relationship.key).append(instance)
def get_instance(self, key, parent_instance): instance = None if key == '-': if not uses_list(self.relationship): instance = getattr( parent_instance, self.relationship.key, None) else: # Allow if it happens to be a singleton. instances = getattr(parent_instance, self.relationship.key) if len(instances) == 1: return instances[0] raise KeyError() else: instance = self.collection_class.get_instance(key) # Validate that the instance belongs to the collection... if instance and not self.contains(parent_instance, instance): raise KeyError("This instance does not live in this collection.") return instance