def field(cls, field_name): """ Returns a Field object for the given name. Args: field_name (str): Field name, Python (snake-case) convention. Return: Field object Raises: InvalidAttributeError: in case this DB object type does not contain a field with the given name. """ field_obj = getattr(cls, field_name, None) if not isinstance(field_obj, Field): raise InvalidAttributeError(cls, field_name) return field_obj
def check_order_by_clause(entity, order_by): """ Checks that the `order_by` clause field is a part of `entity`. Args: entity (type): An Entity subclass type. order_by ((field, ordering)): The ordering tuple consisting of a field and sort ordering (ascending or descending). Return: bool indicating if `order_by` is legal for `entity`. """ if order_by is not None: field, _ = order_by if field not in entity.fields(): raise InvalidAttributeError(entity, field)
def attribute(cls, attribute_name): """ Returns a Field or a Relationship object for the given name. Args: attribute_name (str): Field or Relationship name, Python (snake-case) convention. Return: Field or Relationship object Raises: InvalidAttributeError: in case this DB object type does not contain an attribute with the given name. """ attribute_object = getattr(cls, attribute_name, None) if not isinstance(attribute_object, (Field, Relationship)): raise InvalidAttributeError(cls, attribute_name) return attribute_object
def convert_item(item): # Convert string names to fields. item = { key if isinstance(key, Field) else DataRow.field(key): value for key, value in item.items() } if DataRow.row_data not in item: raise InvalidQueryError( "DataRow.row_data missing when creating DataRow.") invalid_keys = set(item) - set(DataRow.fields()) if invalid_keys: raise InvalidAttributeError(DataRow, invalid_keys) # Item is valid, convert it to a dict {graphql_field_name: value} # Need to change the name of DataRow.row_data to "data" return { "data" if key == DataRow.row_data else key.graphql_name: value for key, value in item.items() }
def update(self, **kwargs): """ Updates this DB object with new values. Values should be passed as key-value arguments with field names as keys: >>> db_object.update(name="New name", title="A title") Kwargs: Key-value arguments defining which fields should be updated for which values. Keys must be field names in this DB object's type. Raise: InvalidAttributeError: if there exists a key in `kwargs` that's not a field in this object type. """ values = {self.field(name): value for name, value in kwargs.items()} invalid_fields = set(values) - set(self.fields()) if invalid_fields: raise InvalidAttributeError(type(self), invalid_fields) query_string, params = query.update_fields(self, values) res = self.client.execute(query_string, params) res = res["update%s" % utils.title_case(self.type_name())] self._set_field_values(res)
def check_where_clause(entity, where): """ Checks the `where` clause of a query. A `where` clause is legal if it only refers to fields found in the entity it's defined for. Since only AND logical operations are supported server-side at the moment, logical OR and NOT are illegal. Args: entity (type): An Entity subclass type. where (LogicalExpression or Comparison): The `where` clause of query. Return: bool indicating if `where` is legal for `entity`. """ def fields(where): """ Yields all the fields in a `where` clause. """ if isinstance(where, LogicalExpression): for f in chain(fields(where.first), fields(where.second)): yield f elif isinstance(where, Comparison): yield where.field # The `deleted` field is a special case, ignore it. where_fields = [f for f in fields(where) if f != Entity.deleted] invalid_fields = set(where_fields) - set(entity.fields()) if invalid_fields: raise InvalidAttributeError(entity, invalid_fields) if len(set(where_fields)) != len(where_fields): raise InvalidQueryError( "Where clause contains multiple comparisons for " "the same field: %r." % where) if set(logical_ops(where)) not in (set(), {LogicalExpression.Op.AND}): raise InvalidQueryError( "Currently only AND logical ops are allowed in " "the where clause of a query.")