In google appengine NDB there are queries like this:
query = Account.query(Account.userid >= 40)
How come the Account.userid >= 40
expression is not expanded at call time to true or false before passed as an argument? How is the filter expression passed to the query? Is it done with operator overloading?
Ignacio is correct, the NDB code is defining custom magic methods on its Property
class for comparison checking. These functions (__eq__
, __ne__
, __lt__
, etc.) are all calling this custom _comparison
function under the hood.
def _comparison(self, op, value):
"""Internal helper for comparison operators.
Args:
op: The operator ('=', '<' etc.).
Returns:
A FilterNode instance representing the requested comparison.
"""
# NOTE: This is also used by query.gql().
if not self._indexed:
raise datastore_errors.BadFilterError(
'Cannot query for unindexed property %s' % self._name)
from .query import FilterNode # Import late to avoid circular imports.
if value is not None:
value = self._do_validate(value)
value = self._call_to_base_type(value)
value = self._datastore_type(value)
return FilterNode(self._name, op, value)
As you can see, the code doesn't return a boolean result, it returns an instance of FilterNode
which itself evaluates to a truthy/falsey value appropriately for the comparison.
How come the
Account.userid >= 40
expression is not expanded at call time to true or false before passed as an argument?
It technically is getting expanded/evaluated before the query()
function is called, it just isn't evaluating to a boolean value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With