1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
"""Evaluating SQL expressions on ORM objects"""
from sqlalchemy import String, Integer, bindparam
from sqlalchemy.testing.schema import Table
from sqlalchemy.testing.schema import Column
from sqlalchemy.testing import fixtures
from sqlalchemy import and_, or_, not_
from sqlalchemy.orm import evaluator
from sqlalchemy.orm import mapper
compiler = evaluator.EvaluatorCompiler()
def eval_eq(clause, testcases=None):
evaluator = compiler.process(clause)
def testeval(obj=None, expected_result=None):
assert evaluator(obj) == expected_result, \
"%s != %r for %s with %r" % (
evaluator(obj), expected_result, clause, obj)
if testcases:
for an_obj, result in testcases:
testeval(an_obj, result)
return testeval
class EvaluateTest(fixtures.MappedTest):
@classmethod
def define_tables(cls, metadata):
Table('users', metadata,
Column('id', Integer, primary_key=True),
Column('name', String(64)))
@classmethod
def setup_classes(cls):
class User(cls.Basic):
pass
@classmethod
def setup_mappers(cls):
users, User = cls.tables.users, cls.classes.User
mapper(User, users)
def test_compare_to_value(self):
User = self.classes.User
eval_eq(User.name == 'foo', testcases=[
(User(name='foo'), True),
(User(name='bar'), False),
(User(name=None), None),
])
eval_eq(User.id < 5, testcases=[
(User(id=3), True),
(User(id=5), False),
(User(id=None), None),
])
def test_compare_to_callable_bind(self):
User = self.classes.User
eval_eq(
User.name == bindparam('x', callable_=lambda: 'foo'),
testcases=[
(User(name='foo'), True),
(User(name='bar'), False),
(User(name=None), None),
]
)
def test_compare_to_none(self):
User = self.classes.User
eval_eq(User.name == None, testcases=[
(User(name='foo'), False),
(User(name=None), True),
])
def test_true_false(self):
User = self.classes.User
eval_eq(
User.name == False, testcases=[
(User(name='foo'), False),
(User(name=True), False),
(User(name=False), True),
]
)
eval_eq(
User.name == True, testcases=[
(User(name='foo'), False),
(User(name=True), True),
(User(name=False), False),
]
)
def test_boolean_ops(self):
User = self.classes.User
eval_eq(and_(User.name == 'foo', User.id == 1), testcases=[
(User(id=1, name='foo'), True),
(User(id=2, name='foo'), False),
(User(id=1, name='bar'), False),
(User(id=2, name='bar'), False),
(User(id=1, name=None), None),
])
eval_eq(or_(User.name == 'foo', User.id == 1), testcases=[
(User(id=1, name='foo'), True),
(User(id=2, name='foo'), True),
(User(id=1, name='bar'), True),
(User(id=2, name='bar'), False),
(User(id=1, name=None), True),
(User(id=2, name=None), None),
])
eval_eq(not_(User.id == 1), testcases=[
(User(id=1), False),
(User(id=2), True),
(User(id=None), None),
])
def test_null_propagation(self):
User = self.classes.User
eval_eq((User.name == 'foo') == (User.id == 1), testcases=[
(User(id=1, name='foo'), True),
(User(id=2, name='foo'), False),
(User(id=1, name='bar'), False),
(User(id=2, name='bar'), True),
(User(id=None, name='foo'), None),
(User(id=None, name=None), None),
])
|