Ejemplo n.º 1
0
    def test_copy(self):

        qlObjs = QueryableListObjs(self.dataObjs)

        assert copy.copy(
            qlObjs) == qlObjs, "Expected copy to equal the original"

        assert id(copy.copy(qlObjs)) != id(
            qlObjs), 'Expected id of copy to not euqla original'

        assert copy.deepcopy(
            qlObjs) != qlObjs, "Expected deepcopy to NOT equal the original"

        assert copy.deepcopy(qlObjs).count() == qlObjs.count(
        ), 'Expected deepcopy to have same number of items'

        aObjs = qlObjs.filter(a='one')

        assert copy.copy(
            aObjs
        ) == aObjs, 'After filter, expected copy to equal filtered original'

        assert id(copy.copy(aObjs)) != id(
            aObjs
        ), 'After filter, expected id of copy to not equal id of filtered original'

        assert copy.deepcopy(
            aObjs
        ) != aObjs, 'After filter, expected deepcopy to NOT equal filtered original'

        assert copy.deepcopy(aObjs).count() == aObjs.count(
        ), 'Expected deepcopy to have same number of items'
Ejemplo n.º 2
0
    def test_sub(self):

        testHasItems = self._testHasItems

        set1Nums = [0, 1, 5, 1, 3]
        set2Nums = [3, 1]
        set3Nums = [0, 5]

        qObjs1 = QueryableListObjs(gdo(self, set1Nums))
        qObjs2 = QueryableListObjs(gdo(self, set2Nums))

        subRes = qObjs1 - qObjs2

        # Assert sub removes items in 2 from 1
        testHasItems(subRes, gdo(self, set3Nums),
                     mkOpStr('o', set1Nums, '-', set2Nums, set3Nums))

        # Assert originals are unchanged
        testHasItems(qObjs1, gdo(self, set1Nums), mkNumSet('o', set1Nums))
        testHasItems(qObjs2, gdo(self, set2Nums), mkNumSet('o', set2Nums))

        qDicts1 = QueryableListDicts(gdd(self, set1Nums))
        qDicts2 = QueryableListDicts(gdd(self, set2Nums))

        subRes = qDicts1 - qDicts2

        # Assert sub removes items in 2 from 1
        testHasItems(subRes, gdd(self, set3Nums),
                     mkOpStr('d', set1Nums, '-', set2Nums, set3Nums))

        # Assert originals are unchanged
        testHasItems(qDicts1, gdd(self, set1Nums), mkNumSet('d', set1Nums))
        testHasItems(qDicts2, gdd(self, set2Nums), mkNumSet('d', set2Nums))
Ejemplo n.º 3
0
    def test_add(self):

        testHasItems = self._testHasItems

        set1Nums = [0, 1]
        set2Nums = [3, 5]
        set3Nums = [0, 1, 3, 5]

        qObjs1 = QueryableListObjs(gdo(self, set1Nums))
        qObjs2 = QueryableListObjs(gdo(self, set2Nums))

        addRes = qObjs1 + qObjs2

        # Assert add appends 2 to 1
        testHasItems(addRes, gdo(self, set3Nums),
                     mkOpStr('o', set1Nums, '+', set2Nums, set3Nums))

        # Assert originals are unchanged
        testHasItems(qObjs1, gdo(self, set1Nums))
        testHasItems(qObjs2, gdo(self, set2Nums))

        qDicts1 = QueryableListDicts(gdd(self, set1Nums))
        qDicts2 = QueryableListDicts(gdd(self, set2Nums))

        addRes = qDicts1 + qDicts2

        # Assert add appends 2 to 1
        testHasItems(addRes, gdd(self, set3Nums),
                     mkOpStr('d', set1Nums, '+', set2Nums, set3Nums))

        # Assert originals are unchanged
        testHasItems(qDicts1, gdd(self, set1Nums), mkNumSet('d', set1Nums))
        testHasItems(qDicts2, gdd(self, set2Nums), mkNumSet('d', set2Nums))
Ejemplo n.º 4
0
	def __init__(self, val=None, mdl=None):
		'''
			__init__ - Create this object

			@param val - None for empty list, IndexedRedisModel for a one-item list, or a list/tuple or subclass of initial values.
			@param mdl - The IndexedRedisModel that this list will contain. Provide this now if you can, otherwise it will be inferred from
			  the first item added or present in the list.

			@raises ValueError if "mdl" is not an IndexedRedisModel
		'''
		if val is None:
			QueryableListObjs.__init__(self)
		else:
			QueryableListObjs.__init__(self, val)


		self.mdl = mdl

		if not mdl:
			# If not explicitly defined, try to infer model if objects were provided.
			#  otherwise, inference will be attempted when an operation that requires it is performed.
			self.mdl = self.getModel()
		else:
			# This is called in getModel() if we did infer, so no need to call twice.
			self.__validate_model(mdl)
Ejemplo n.º 5
0
    def test_performance(self):
        # Test __eq and = both
        qlObjs = QueryableListObjs(self.dataObjs)
        qlDicts = QueryableListDicts(self.dataDicts)

        start = time.time()

        for i in range(1, NUMI + 1, 1):
            filterA = 'x' * ((i * 7) % 5)
            filterA2 = 'x' * ((i * 13) % 5)

            filterB = 'y' * ((i * 11) % 5)
            filterB2 = 'y' * ((i * 3) % 5)

            filterNums1 = [(i * 100) % 5, (i * 33) % 5, (i * 121) % 5]
            filterNums2 = [(i * 177) % 5, (i * 62) % 5, (i * 101) % 5]

            res = qlObjs.filter(
                a=filterA,
                a__ne=filterB,
                b__in=[filterB[:min(len(filterB) - 1, 1)],
                       filterB]).filterOr(num__gt=filterNums1[i % 3],
                                          num__ne=filterNums2[i % 3])

        end = time.time()

        print("Total time: %f" % (end - start, ))
    def test_Dicts(self):

        gotException = False

        try:
            qlDicts = QueryableListDicts(self.dataDicts)
            found = qlDicts.filter(a='one')
        except Exception as e:
            gotException = e

        assert gotException is False, 'Got Exception for QueryableListDicts when should not have: %s%s' % (
            str(type(e)), str(e))
        assert len(found) == 2, 'Did not find correct number of items'

        gotException = False
        try:
            dDicts = QueryableListObjs(self.dataDicts)
            found = dDicts.filter(a='one')
        except Exception as e:
            # I personally think this should raise an exception, so test is written like this,
            #  but it would be too performant loss to check every time.
            gotException = e

        #assert gotException is not False, 'Expected to get exception, but did not.'
        assert len(
            found
        ) == 0, 'Expected not to find any items when using QueryableListDicts with list of objs'
Ejemplo n.º 7
0
    def test_isub(self):
        testHasItems = self._testHasItems

        set1Nums = [0, 1, 5, 1, 3]  # A
        set2Nums = [3, 1]  # B

        set3Nums = [0, 5]  # = C

        qObjs1 = QueryableListObjs(gdo(self, [0, 1, 5, 1, 3]))
        qObjs2 = QueryableListObjs(gdo(self, [3, 1]))

        origRef1 = qObjs1

        origID1 = id(qObjs1)

        qObjs1 -= qObjs2

        # Assert sub removes items from 1 that are in 2
        testHasItems(qObjs1, gdo(self, set3Nums),
                     mkOpStr('o', set1Nums, '-', set2Nums, set3Nums))

        # Assert original1 is modified, 2 is not
        testHasItems(qObjs1, gdo(self, set3Nums),
                     'o1 = ' + mkNumSet('o', set3Nums))
        testHasItems(qObjs2, gdo(self, set2Nums),
                     'o2 = ' + mkNumSet('o', set2Nums))

        afterID1 = id(qObjs1)

        assert origID1 == afterID1, 'Expected id to not change after iadd (i.e. a copy was not made.)\nBefore = %d\nAfter  = %d' % (
            origID1, afterID1)
        testHasItems(origRef1, gdo(self, set3Nums),
                     'o1ref = ' + mkNumSet('o', set3Nums))

        qDicts1 = QueryableListDicts(gdd(self, set1Nums))
        qDicts2 = QueryableListDicts(gdd(self, set2Nums))

        origRef1 = qDicts1

        origID1 = id(qDicts1)

        qDicts1 -= qDicts2

        # Assert sub removes items from 1 that are in 2
        testHasItems(qDicts1, gdd(self, set3Nums),
                     mkOpStr('d', set1Nums, '-=', set2Nums))

        # Assert original1 is modified, 2 is not
        testHasItems(qDicts1, gdd(self, set3Nums),
                     'd1 = ' + mkNumSet('d', set3Nums))
        testHasItems(qDicts2, gdd(self, set2Nums),
                     'd1 = ' + mkNumSet('d', set2Nums))

        afterID1 = id(qDicts1)

        assert origID1 == afterID1, 'Expected id to not change after iadd (i.e. a copy was not made.)\nBefore = %d\nAfter  = %d' % (
            origID1, afterID1)
        testHasItems(origRef1, gdd(self, set3Nums),
                     'd1ref = ' + mkNumSet('d', set3Nums))
Ejemplo n.º 8
0
    def test_ne(self):
        qlObjs = QueryableListObjs(self.dataObjs)

        found = qlObjs.filter(a__ne='one')

        assert len(
            found) == 1, 'Expected to find one item in query, found %d' % (
                len(found), )

        assert found[0].a == 'six' and found[
            0].c == 'eleven', 'Found wrong item from equals query'
Ejemplo n.º 9
0
    def test_chaining(self):
        qlObjs = QueryableListObjs(self.dataObjs)

        found = qlObjs.filter(a__eq='one').filter(b__eq='two')

        assert len(
            found
        ) == 1, 'Expected chained filter to return one element, got %d' % (
            len(found), )

        assert found[0].a == 'one' and found[
            0].b == 'two', 'Got wrong item in chained query'
Ejemplo n.º 10
0
    def test_iadd(self):
        testHasItems = self._testHasItems

        set1Nums = [0, 1]
        set2Nums = [3, 5]
        set3Nums = [0, 1, 3, 5]

        qObjs1 = QueryableListObjs(gdo(self, set1Nums))
        qObjs2 = QueryableListObjs(gdo(self, set2Nums))

        origRef1 = qObjs1

        origID1 = id(qObjs1)

        qObjs1 += qObjs2

        # Assert add appends 2 to 1
        testHasItems(qObjs1, gdo(self, set3Nums),
                     mkOpStr('o', set1Nums, '+=', set2Nums))

        # Assert original1 is modified, 2 is not
        testHasItems(qObjs1, gdo(self, set3Nums), mkNumSet('o', set3Nums))
        testHasItems(qObjs2, gdo(self, set2Nums), mkNumSet('o', set2Nums))

        afterID1 = id(qObjs1)

        assert origID1 == afterID1, 'Expected id to not change after iadd (i.e. a copy was not made.)\nBefore = %d\nAfter  = %d' % (
            origID1, afterID1)

        testHasItems(origRef1, gdo(self, set3Nums), mkNumSet('o', set3Nums))

        qDicts1 = QueryableListDicts(gdd(self, set1Nums))
        qDicts2 = QueryableListDicts(gdd(self, set2Nums))

        origRef1 = qDicts1

        origID1 = id(qDicts1)

        qDicts1 += qDicts2

        # Assert add appends 2 to 1
        testHasItems(qDicts1, gdd(self, set3Nums),
                     mkOpStr('d', set1Nums, '+', set2Nums, set3Nums))

        # Assert original1 is modified, 2 is not
        testHasItems(qDicts1, gdd(self, set3Nums), mkNumSet('d', set3Nums))
        testHasItems(qDicts2, gdd(self, set2Nums), mkNumSet('d', set2Nums))

        afterID1 = id(qDicts1)

        assert origID1 == afterID1, 'Expected id to not change after iadd (i.e. a copy was not made.)\nBefore = %d\nAfter  = %d' % (
            origID1, afterID1)
        testHasItems(origRef1, gdd(self, set3Nums), mkNumSet('d', set3Nums))
Ejemplo n.º 11
0
    def test_filterOr(self):
        qlObjs = QueryableListObjs(self.dataObjs)

        found = qlObjs.filterOr(a='six', b='five')

        assert len(
            found
        ) == 2, 'Expected "or" filter to return 2 items for a="6" and b="five". Got: %s\n' % (
            str(found), )

        assert (
            (found[0].a == 'six' or found[0].b == 'five')
            or (found[1].a == 'six' or found[1].b == 'five')
        ), 'Got wrong items for a="6" and b="five". Got: %s' % (str(found), )
Ejemplo n.º 12
0
    def test_equals(self):
        # Test __eq and = both
        qlObjs = QueryableListObjs(self.dataObjs)

        found = qlObjs.filter(a='six')

        assert len(
            found) == 1, 'Expected to find one item in query(=), found %d' % (
                len(found), )

        assert found[0].a == 'six' and found[
            0].c == 'eleven', 'Found wrong item from equals query'

        found = qlObjs.filter(a__eq='six')
        assert len(
            found
        ) == 1, 'Expected to find one item in query(__eq), found %d' % (
            len(found), )

        assert found[0].a == 'six' and found[
            0].c == 'eleven', 'Found wrong item from equals query'

        found = QueryableListObjs(self.dataObjs).filter(a__eq='one')

        assert len(
            found) == 2, 'Expected to find two items in query, found %d' % (
                len(found), )
        assert found.count(
        ) == 2, 'Expected count() to return 2 elements. Got: %d' % (
            found.count(), )
Ejemplo n.º 13
0
    def test_customMatch(self):
        dataObjs = self.dataObjs
        doTest = self._doTest

        qlObjs = QueryableListObjs(dataObjs)

        doTest(qlObjs, 'AND', {'q__customMatch': lambda q: q and len(q) > 5},
               (dataObjs[0], dataObjs[1]))
Ejemplo n.º 14
0
    def test_all(self):
        qlObjs = QueryableListObjs(self.dataObjs)

        qlObjsAll = qlObjs.all()

        assert qlObjsAll == qlObjs, 'Expected .all() to equal original'

        assert id(qlObjsAll) != id(
            qlObjs), 'Expected id of .all() to not equal id of original'

        aObjs = qlObjs.filter(a='one')
        aObjsAll = aObjs.all()

        assert aObjs == aObjsAll, 'After filter, Expected .all() to equal filtered original'

        assert id(aObjs) != id(
            aObjsAll
        ), 'After filter, expected id of .all() NOT to equal id of filtered original'
Ejemplo n.º 15
0
    def test_ne(self):
        dataObjs = self.dataObjs
        doTest = self._doTest

        qlObjs = QueryableListObjs(dataObjs)

        doTest(qlObjs, 'AND', {'a__ne': 'one'}, (dataObjs[2], ))
        doTest(qlObjs, 'OR', {
            'b__ne': 'two',
            'num__ne': -5
        }, (dataObjs[0], dataObjs[1], dataObjs[2]))
Ejemplo n.º 16
0
    def text_mixed(self):
        dataObjs = self.dataObjs
        doTest = self._doTest

        qlObjs = QueryableListObjs(dataObjs)

        doTest(qlObjs, 'AND', {'a__eq': 'six', 'num__ne': 7}, tuple())
        doTest(qlObjs, 'AND', {
            'a__eq': 'one',
            'num__ne': 7
        }, tuple(dataObjs[1]))
Ejemplo n.º 17
0
    def test_eq(self):
        dataObjs = self.dataObjs
        doTest = self._doTest

        qlObjs = QueryableListObjs(dataObjs)

        doTest(qlObjs, 'AND', {'a__eq': 'one'}, (dataObjs[0], dataObjs[1]))
        doTest(qlObjs, 'OR', {
            'b__eq': 'five',
            'num__eq': 7
        }, (dataObjs[0], dataObjs[1], dataObjs[2]))
        doTest(qlObjs, 'AND', {'a__eq': 'nine'}, tuple())
Ejemplo n.º 18
0
    def test_sortObjsByInt(self):

        dataObjs = self.dataObjs

        qlObjs = QueryableListObjs(self.dataObjs)

        sortedByA = qlObjs.sort_by('a')

        sortedByAList = list(sortedByA)

        expectedList = [dataObjs[0], dataObjs[3], dataObjs[2], dataObjs[1]]

        assert sortedByAList == expectedList, 'Sort by field "a" failed to return expected order.\nGot:      %s\nExpected: %s\n' % (
            repr(self._get_list_of_values(sortedByAList, 'a')),
            repr(self._get_list_of_values(expectedList, 'a')))

        assert dataObjs == self.dataObjsCopy, 'Expected sort_by to not modify original list'

        assert isinstance(
            sortedByA, QueryableListObjs
        ), 'Expected return to be a QueryableListObjs instance. Got: %s' % (
            sortedByA.__class__.__name__, )

        sortedByARev = qlObjs.sort_by('a', reverse=True)
        sortedByARevList = list(sortedByARev)

        expectedRevList = list(reversed(expectedList))

        assert sortedByARevList == expectedRevList, 'Reverse sort by field "a" failed to return expected order.\nGot:      %s\nExpected: %s\n' % (
            repr(self._get_list_of_values(sortedByARevList, 'a')),
            repr(self._get_list_of_values(expectedRevList, 'a')))

        assert dataObjs == self.dataObjsCopy, 'Expected sort_by to not modify original list'

        assert isinstance(
            sortedByARev, QueryableListObjs
        ), 'Expected return to be a QueryableListObjs instance. Got: %s' % (
            sortedByARev.__class__.__name__, )
Ejemplo n.º 19
0
    def test_gt(self):
        dataObjs = self.dataObjs
        doTest = self._doTest

        qlObjs = QueryableListObjs(dataObjs)

        doTest(qlObjs, 'AND', {'num__gt': 8}, tuple())
        doTest(qlObjs, 'OR', {
            'num__gt': 0,
        }, (dataObjs[0], dataObjs[2]))
        doTest(qlObjs, 'AND', {'num__gt': 7}, tuple())
        doTest(qlObjs, 'AND', {'num__gt': -5}, (dataObjs[0], dataObjs[2]))
        doTest(qlObjs, 'AND', {'num__gt': -6},
               (dataObjs[0], dataObjs[1], dataObjs[2]))
    def test_Dicts(self):

        gotException = False

        try:
            qlDicts = QueryableListDicts(self.dataDicts)
            found = qlDicts.filter(a='one')
        except Exception as e:
            gotException = e

        assert gotException is False, 'Got Exception for QueryableListDicts when should not have: %s%s' %(str(type(e)), str(e)) 
        assert len(found) == 2, 'Did not find correct number of items'

        gotException = False
        try:
            dDicts = QueryableListObjs(self.dataDicts)
            found = dDicts.filter(a='one')
        except Exception as e:
            # I personally think this should raise an exception, so test is written like this,
            #  but it would be too performant loss to check every time.
            gotException = e

        #assert gotException is not False, 'Expected to get exception, but did not.'
        assert len(found) == 0, 'Expected not to find any items when using QueryableListDicts with list of objs'
Ejemplo n.º 21
0
    def __init__(self, val=None, mdl=None):
        '''
			__init__ - Create this object

			@param val - None for empty list, IndexedRedisModel for a one-item list, or a list/tuple or subclass of initial values.
			@param mdl - The IndexedRedisModel that this list will contain. Provide this now if you can, otherwise it will be inferred from
			  the first item added or present in the list.

			@raises ValueError if "mdl" is not an IndexedRedisModel
		'''
        if val is None:
            QueryableListObjs.__init__(self)
        else:
            QueryableListObjs.__init__(self, val)

        self.mdl = mdl

        if not mdl:
            # If not explicitly defined, try to infer model if objects were provided.
            #  otherwise, inference will be attempted when an operation that requires it is performed.
            self.mdl = self.getModel()
        else:
            # This is called in getModel() if we did infer, so no need to call twice.
            self.__validate_model(mdl)
Ejemplo n.º 22
0
    def test_lt(self):
        dataObjs = self.dataObjs
        doTest = self._doTest

        qlObjs = QueryableListObjs(dataObjs)

        doTest(qlObjs, 'AND', {'num__lt': 8}, (
            dataObjs[0],
            dataObjs[1],
            dataObjs[2],
        ))
        doTest(qlObjs, 'OR', {
            'num__lt': 0,
        }, (dataObjs[1], ))
        doTest(qlObjs, 'AND', {'num__lt': 7}, (dataObjs[1], ))
Ejemplo n.º 23
0
    def test_customFilter(self):
        dataObjs = self.dataObjs
        doTest = self._doTest

        qlObjs = QueryableListObjs(dataObjs)

        matchFunc = lambda item: getattr(item, 'b', None) and item.num > 0

        results = qlObjs.customFilter(matchFunc)

        assert len(results) == 1, 'Expected to get one result, got %d' % (
            len(results), )

        assert results[0] == dataObjs[0]

        matchFunc = lambda item: item.a.upper() == 'ONE'

        results = qlObjs.customFilter(matchFunc)

        assert len(results) == 2, 'Expected to get two results, got %d' % (
            len(results), )

        assert dataObjs[0] in results, 'Expected dataObjs[0] to be in match'
        assert dataObjs[1] in results, 'Expected dataObjs[1] to be in match'
Ejemplo n.º 24
0
    def test_ne(self):
        dataObjs = self.dataObjs
        doTest = self._doTest

        qlObjs = QueryableListObjs(dataObjs)

        doTest(qlObjs, 'AND', {'a__ne': 'six'}, (dataObjs[0], dataObjs[1]))
        doTest(qlObjs, 'AND', {'a__ne': 'five'},
               (dataObjs[0], dataObjs[1], dataObjs[2]))
        doTest(qlObjs, 'AND', {'num__ne': -5, 'a__ne': 'one'}, (dataObjs[2], ))
        doTest(qlObjs, 'AND', {'num__ne': -5, 'a__ne': 'six'}, (dataObjs[0], ))

        doTest(qlObjs, 'OR', {
            'a__ne': 'one',
            'q__ne': 'cheese'
        }, (dataObjs[2], ))
        doTest(qlObjs, 'OR', {
            'a__ne': 'six',
            'num__ne': -5
        }, (dataObjs[0], dataObjs[1], dataObjs[2]))
Ejemplo n.º 25
0
    def test_eq(self):
        # Test __eq and = both
        dataObjs = self.dataObjs
        doTest = self._doTest

        qlObjs = QueryableListObjs(dataObjs)

        doTest(qlObjs, 'AND', {'a': 'six'}, (dataObjs[2], ))
        doTest(qlObjs, 'AND', {'a__eq': 'six'}, (dataObjs[2], ))
        doTest(qlObjs, 'AND', {'a': 'one'}, (dataObjs[0], dataObjs[1]))
        doTest(qlObjs, 'AND', {
            'a': 'one',
            'emptyStr': ''
        }, (dataObjs[0], dataObjs[1]))
        doTest(qlObjs, 'AND', {
            'a': 'one',
            'q': 'cheese'
        }, (dataObjs[0], dataObjs[1]))
        doTest(qlObjs, 'AND', {
            'emptyStr': '',
            'num__eq': 7
        }, (dataObjs[0], dataObjs[2]))

        doTest(qlObjs, 'OR', {'a': 'six'}, (dataObjs[2], ))
        doTest(qlObjs, 'OR', {'a__eq': 'six'}, (dataObjs[2], ))
        doTest(qlObjs, 'OR', {
            'a': 'one',
            'q__eq': 'bacon'
        }, (dataObjs[0], dataObjs[1], dataObjs[2]))
        doTest(qlObjs, 'OR', {
            'a': 'one',
            'emptyStr': ''
        }, (dataObjs[0], dataObjs[1], dataObjs[2]))
        doTest(qlObjs, 'OR', {
            'a': 'six',
            'num__eq': 7
        }, (dataObjs[0], dataObjs[2]))
Ejemplo n.º 26
0
    # a mixed dataset of objects and dicts
    dataset2 = [ 
        SampleDataObj(colour='blue', age=25, name='Tim', likes=['batteries', 'cheese']),
        SampleDataObj(colour='red', age=55, name='Jack', likes=['puppies', 'milk']),
        {
            'colour' : 'green', 'age' : 88, 'name' : 'John', 'likes' : ['puppies', 'games']
        },
        {
            'colour' : 'orange', 'age' : 18, 'name' : 'Phil', 'likes' : ['puppies', 'gnomes']
        },
    ]

    
#    data = QueryableListDicts(data)
    data = QueryableListObjs(data)

    sys.stdout.write("Data: %s\n\n" %(data,))

    sys.stdout.write('People who are over 22 years old:\n%s\n\n' %(data.filter(age__gt=22),))

#    sys.stdout.write('People who like puppies or bricks, and their favourite colour is purple:\n\n' %(data.filter(likes__containsAny=('puppies', 'bricks')).filter(colour__ieq='purple'),))
    sys.stdout.write('People who like puppies or bricks, and their favourite colour is purple:\n%s\n\n' %(data.filter(likes__containsAny=('puppies', 'bricks'), colour__ieq='purple'),))

    sys.stdout.write('People who are at least 30 years old or like cheese:\n%s\n\n' %(data.filterOr(likes__contains='cheese', age__gte=30),))


    # Create a QueryBuilder to execute a query
    builder = QueryBuilder()
    builder.addFilter("AND", age__gt=22)
    builder.addFilter(likes__contains='puppies')