def test_or(): q = Query(T, None) want = { '$or' : [{'i' : 3}, {'i' : 4}, {'i' : 5}] } assert q.filter((T.i == 3) | (T.i == 4) | (T.i == 5)).query == want assert Query(T, None).or_(T.i == 3, T.i == 4, T.i == 5).query == want
def computed_field_wrap_value_func_test(): class TestDoc2(Document): @computed_field(StringField()) def c(obj): return 'foo' Query(TestDoc2, None).in_(TestDoc2.c, 'bar').query == {'c': {'$in': 'bar'}}
def __init__(self, trans_id, session, document, safe, id_expression=None, upsert=False, update_ops={}, **kwargs): from mongoalchemy.query import Query self.session = session self.trans_id = trans_id self.type = type(document) self.safe = safe self.upsert = upsert if id_expression: self.db_key = Query(self.type, session).filter(id_expression).query else: self.db_key = {'_id': document.mongo_id} self.dirty_ops = document.get_dirty_ops(with_required=upsert) for key, op in chain(update_ops.items(), kwargs.items()): key = str(key) for current_op, keys in self.dirty_ops.items(): if key not in keys: continue self.dirty_ops.setdefault(op, {})[key] = keys[key] del self.dirty_ops[current_op][key] if len(self.dirty_ops[current_op]) == 0: del self.dirty_ops[current_op] document._mark_clean()
def test_nin(): q = Query(T, None) assert q.nin(T.i, 1, 2, 3).query == { 'i': { '$nin': [1, 2, 3] } }, q.nin(T.i, 1, 2, 3).query assert q.filter(T.i.nin(1, 2, 3)).query == {'i': {'$nin': [1, 2, 3]}}
def test_in(): q = Query(T, None) assert q.in_(T.i, 1, 2, 3).query == { 'i': { '$in': [1, 2, 3] } }, q.in_(T.i, 1, 2, 3).query assert q.filter(T.i.in_(1, 2, 3)).query == {'i': {'$in': [1, 2, 3]}}
def update(self, item, id_expression=None, upsert=False, update_ops={}, safe=None, **kwargs): ''' Update an item in the database. Uses the on_update keyword to each field to decide which operations to do, or. :param item: An instance of a :class:`~mongoalchemy.document.Document` \ subclass :param id_expression: A query expression that uniquely picks out \ the item which should be updated. If id_expression is not \ passed, update uses item.mongo_id. :param upsert: Whether the update operation should be an upsert. \ If the item may not be in the database yet this should be True :param update_ops: By default the operation used to update a field \ is specified with the on_update argument to its constructor. \ To override that value, use this dictionary, with \ :class:`~mongoalchemy.document.QueryField` objects as the keys \ and the mongo operation to use as the values. :param kwargs: The kwargs are merged into update_ops dict to \ decide which fields to update the operation for. These can \ only be for the top-level document since the keys \ are just strings. .. warning:: This operation is **experimental** and **not fully tested**, although it does have code coverage. ''' if id_expression: db_key = Query(type(item), self).filter(id_expression).query else: db_key = {'_id': item.mongo_id} dirty_ops = item.get_dirty_ops(with_required=upsert) for key, op in chain(list(update_ops.items()), list(kwargs.items())): key = str(key) for current_op, keys in list(dirty_ops.items()): if key not in keys: continue dirty_ops.setdefault(op, {})[key] = keys[key] del dirty_ops[current_op][key] if len(dirty_ops[current_op]) == 0: del dirty_ops[current_op] if safe is None: safe = self.safe self.flush(safe=safe) self.db[item.get_collection_name()].update(db_key, dirty_ops, upsert=upsert, safe=safe)
def query(self, type): ''' Begin a query on the database's collection for `type`. If `type` is an instance of basesting, the query will be in raw query mode which will not check field values or transform returned results into python objects. .. seealso:: :class:`~mongoalchemy.query.Query` class''' # This really should be adding a query operation to the # queue which is then forced to execute when the results are being # read if isinstance(type, basestring): type = FreeFormDoc(type) return Query(type, self)
def test_exists(): q = Query(T, None) assert q.filter(T.i.exists(False)).query == {'i': {'$exists': False}} assert q.filter(T.i.exists(True)).query == {'i': {'$exists': True}}
def test_not_assign_dict_malformed_field(): class Any(Document): i = AnythingField() not_q = Query(Any, None).not_(Any.i == { 'a' : 4, 'b' : 5}).query assert not_q == { 'i' : { '$ne' : { 'a' : 4, 'b' : 5 } } }, not_q
def test_not_with_malformed_field(): class Any(DocumentField): i = AnythingField() not_q = Query(Any, None).not_(Any.i == { '$gt' : 4, 'garbage' : 5})
def test_not(): not_q = Query(T, None).filter( ~(T.i == 3) ).query assert not_q == { 'i' : {'$ne' : 3} }, not_q not_q = Query(T, None).not_(T.i > 4).query assert not_q == { 'i' : {'$not': { '$gt': 4}} }, not_q