"""Evluating SQL expressions on ORM objects""" import sqlalchemy as sa from sqlalchemy import testing from sqlalchemy import String, Integer, select from sqlalchemy.testing.schema import Table from sqlalchemy.testing.schema import Column from sqlalchemy.orm import mapper, create_session from sqlalchemy.testing import eq_ from sqlalchemy.testing import fixtures from sqlalchemy import and_, or_, not_ from sqlalchemy.orm import evaluator 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_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), ])