def _QueryModel(self, search_dict, ancestor=None): """Queries the model class for field-value pairs. Args: search_dict: A dictionary mapping from field name to search by to the search term. ancestor: ndb.Key, If provided, the ancestor for the query. Returns: The model query. Raises: QueryError: If the queried field is not a property of the model. QueryTypeError: If search_term does not match the type of the search_base model property. """ filter_nodes = [] for search_base, search_term in search_dict.items(): field_name = upvote_utils.CamelToSnakeCase(search_base) # If the model class offers a translation function for property queries, # invoke it and set the field and search term to the result. try: field_name, search_term = self.MODEL_CLASS.TranslatePropertyQuery( field_name, search_term) except AttributeError: pass else: logging.info('Converted query to (%s = %s)', field_name, search_term) # Check for the property on the model itself (as opposed to, say, catching # a getattr exception) to ensure that the field being accessed is an ndb # property as opposed to a Python attribute. if not model_utils.HasProperty(self.MODEL_CLASS, field_name): raise QueryError('Invalid searchBase %s' % field_name) field = getattr(self.MODEL_CLASS, field_name) # If the field is of a non-string type, attempt to coerce the argument to # conform to this type search_term = _CoerceQueryParam(field, search_term) filter_nodes.append(ndb.FilterNode(field_name, '=', search_term)) query = self.MODEL_CLASS.query(ancestor=ancestor) if filter_nodes: query = query.filter(ndb.AND(*filter_nodes)) return query
def testDatetimeAutoNowAdd(self): # Initial schema class A(ndb.Model): a = ndb.StringProperty() b = ndb.DateTimeProperty(auto_now_add=True) # Create an entity using the initial schema inst = A(a='abc') inst.put() # Delete the property and save the entity utils.DeletePropertyValue(inst, 'b') inst.put() self.assertTrue(utils.HasProperty(inst, 'b')) self.assertIsNotNone(inst.b)
def testSameSchema_DoesntDeleteProperty(self): # Initial schema class A(ndb.Model): a = ndb.StringProperty() b = ndb.StringProperty() # Create an entity using the initial schema inst = A(a='abc', b='def') inst.put() # Delete the property and save the entity utils.DeleteProperty(inst, 'b') inst.put() # Create a new instance and verify that the 'b' hasn't disappeared new = A(a='abc', b='def') new.put() self.assertTrue(utils.HasProperty(new, 'b'))