How to create a query for matching keys?
Question: I use the key of another User, the sponsor, to indicate who is the sponsor of
a User and it creates a link in the datastore for those Users that have a
sponsor and it can be at most one but a sponsor can sponsor many users like in
this case ID 2002 who sponsored three other users:

![enter image description here](http://i.stack.imgur.com/76Mwj.png)

In this case this query does what I want: `SELECT * FROM User where sponsor
=KEY('agtzfmJuYW5vLXd3d3ILCxIEVXNlchjSDww')` but I don't know how to program
that with python, I can only use it to the datastore. How can I query by key
when I want to match the set of users who has the same user as key in the same
field? A user in my model can have at most one sponsor and I just want to know
who a particular person sponsored which could be a list of users and then they
sponsored users in their turn which I also want to query on.

The field sponsor is a key and it has a link to the sponsor in the datastore.
I set the key just like user2.sponsor = user1.key and now I want to find all
that user1 sponsored with a query that should be just like

`User.All().filter('sponsor = ', user1.key)`

but sponsor is a field of type key so I don't know how to match it to see for
example a list a people the active user is a sponsor for and how it becomes a
tree when the second generation also have links. How to select the list of
users this user is a sponsor for and then the second generation? When i
modelled the relation simply like u1=u2.key ie user2.sponsor=user1.key. Thanks
for any hint

The following workaround is bad practice but is my last and only resort:

    
    
    def get(self):
        auser = self.auth.get_user_by_session()
        realuser = auth_models.User.get_by_id(long( auser['user_id'] ))
        q = auth_models.User.query()
        people = []
        for p in q:
          try:
            if p.sponsor == realuser.key:
               people.append(p)
          except Exception, e:
            pass
        if auser: 
            self.render_jinja('my_organization.html', people=people, user=realuser,)
    

## Update

The issues are that the keyproperty is not required and that Guido Van Rossum
has reported this as a bug in the ndb when I think it's a bug in my code.
Here's what I'm using now, which is a very acceptable solution since every
real user in the organization except possibly programmers, testers and admins
are going the be required to have a sponsor ID which is a user ID.

    
    
    from ndb import query
    class Myorg(NewBaseHandler):
        @user_required
        def get(self):
            user = auth_models.User.get_by_id(long(self.auth.get_user_by_session()['user_id']))
        people = auth_models.User.query(auth_models.User.sponsor == user.key).fetch()
            self.render_jinja('my_organization.html', people=people,
                                  user=user) 
    
    class User(model.Expando):
        """Stores user authentication credentials or authorization ids."""
    
        #: The model used to ensure uniqueness.
        unique_model = Unique
        #: The model used to store tokens.
        token_model = UserToken
        sponsor = KeyProperty()
        created = model.DateTimeProperty(auto_now_add=True)
        updated = model.DateTimeProperty(auto_now=True)
        # ID for third party authentication, e.g. 'google:username'. UNIQUE.
        auth_ids = model.StringProperty(repeated=True)
        # Hashed password. Not required because third party authentication
        # doesn't use password.
        password = model.StringProperty()
        ...
    


Answer: The User model is an NDB Expando which is a little bit tricky to query.

From the [docs](https://docs.google.com/document/d/1dsx1hihmMXMJm8wIRu49tJR-
KEng80o3wkg4Nlbqn-w/edit?hl=en_US#heading=h.j07awmd5m00o)

> Another useful trick is querying an Expando kind for a dynamic property. You
> won't be able to use class.query(class.propname == value) as the class
> doesn't have a property object. Instead, you can use the
> ndb.query.FilterNode class to construct a filter expression, as follows:
    
    
    from ndb import model, query
    
    class X(model.Expando):
      @classmethod
      def query_for(cls, name, value):
        return cls.query(query.FilterNode(name, '=', value))
    
    print X.query_for('blah', 42).fetch()
    

So try:

    
    
    form ndb import query
    
    def get(self):
        auser = self.auth.get_user_by_session()
        realuser = auth_models.User.get_by_id(long( auser['user_id'] ))
        people = auth_models.User.query(query.FilterNode('sponsor', '=', realuser.key)).fetch()
        if auser: 
            self.render_jinja('my_organization.html', people=people, user=realuser,)
    

