Example #1
0
    def make_test(fetchtype):
        def test_roundtrip(self):
            class A(_fixtures.Base):pass
            class B(A):pass
            class C(B):pass

            if fetchtype == 'union':
                abc = a.outerjoin(b).outerjoin(c)
                bc = a.join(b).outerjoin(c)
            else:
                abc = bc = None

            mapper(A, a, with_polymorphic=('*', abc), polymorphic_on=a.c.type, polymorphic_identity='a')
            mapper(B, b, with_polymorphic=('*', bc), inherits=A, polymorphic_identity='b')
            mapper(C, c, inherits=B, polymorphic_identity='c')

            a1 = A(adata='a1')
            b1 = B(bdata='b1', adata='b1')
            b2 = B(bdata='b2', adata='b2')
            b3 = B(bdata='b3', adata='b3')
            c1 = C(cdata='c1', bdata='c1', adata='c1')
            c2 = C(cdata='c2', bdata='c2', adata='c2')
            c3 = C(cdata='c2', bdata='c2', adata='c2')

            sess = create_session()
            for x in (a1, b1, b2, b3, c1, c2, c3):
                sess.add(x)
            sess.flush()
            sess.expunge_all()

            #for obj in sess.query(A).all():
            #    print obj
            assert [
                A(adata='a1'),
                B(bdata='b1', adata='b1'),
                B(bdata='b2', adata='b2'),
                B(bdata='b3', adata='b3'),
                C(cdata='c1', bdata='c1', adata='c1'),
                C(cdata='c2', bdata='c2', adata='c2'),
                C(cdata='c2', bdata='c2', adata='c2'),
            ] == sess.query(A).order_by(A.id).all()

            assert [
                B(bdata='b1', adata='b1'),
                B(bdata='b2', adata='b2'),
                B(bdata='b3', adata='b3'),
                C(cdata='c1', bdata='c1', adata='c1'),
                C(cdata='c2', bdata='c2', adata='c2'),
                C(cdata='c2', bdata='c2', adata='c2'),
            ] == sess.query(B).all()

            assert [
                C(cdata='c1', bdata='c1', adata='c1'),
                C(cdata='c2', bdata='c2', adata='c2'),
                C(cdata='c2', bdata='c2', adata='c2'),
            ] == sess.query(C).all()

        test_roundtrip = function_named(
            test_roundtrip, 'test_%s' % fetchtype)
        return test_roundtrip
def assert_conns_closed(fn):
    def decorated(*args, **kw):
        try:
            fn(*args, **kw)
        finally:
            testing_reaper.assert_all_closed()
    return function_named(decorated, fn.__name__)
Example #3
0
    def decorate(fn):
        def safe(*args, **kw):
            # todo: should probably be strict about this, too
            filters = [dict(action='ignore',
                            category=sa_exc.SAPendingDeprecationWarning)]
            if not messages:
                filters.append(dict(action='ignore',
                                    category=sa_exc.SADeprecationWarning))
            else:
                filters.extend(
                    [dict(action='ignore',
                          message=message,
                          category=sa_exc.SADeprecationWarning)
                     for message in
                     [ (m.startswith('//') and
                        ('Call to deprecated function ' + m[2:]) or m)
                       for m in messages] ])

            for f in filters:
                warnings.filterwarnings(**f)
            try:
                return fn(*args, **kw)
            finally:
                resetwarnings()
        return function_named(safe, fn.__name__)
Example #4
0
def resolve_artifact_names(fn):
    """Decorator, augment function globals with tables and classes.

    Swaps out the function's globals at execution time. The 'global' statement
    will not work as expected inside a decorated function.

    """

    # This could be automatically applied to framework and test_ methods in
    # the MappedTest-derived test suites but... *some* explicitness for this
    # magic is probably good.  Especially as 'global' won't work- these
    # rebound functions aren't regular Python..
    #
    # Also: it's lame that CPython accepts a dict-subclass for globals, but
    # only calls dict methods.  That would allow 'global' to pass through to
    # the func_globals.
    def resolved(*args, **kwargs):
        self = args[0]
        context = dict(fn.func_globals)
        for source in self._artifact_registries:
            context.update(getattr(self, source))
        # jython bug #1034
        rebound = types.FunctionType(fn.func_code, context, fn.func_name,
                                     fn.func_defaults, fn.func_closure)
        return rebound(*args, **kwargs)

    return function_named(resolved, fn.func_name)
Example #5
0
    def decorator(fn):
        def counted(*args, **kw):
            try:
                filename = "%s.prof" % fn.__name__

                elapsed, stat_loader, result = _profile(
                    filename, fn, *args, **kw)

                stats = stat_loader()
                calls = stats.total_calls

                stats.sort_stats('calls', 'cumulative')
                stats.print_stats()
                #stats.print_callers()
                deviance = int(count * variance)
                if (calls < (count - deviance) or
                    calls > (count + deviance)):
                    raise AssertionError(
                        "Function call count %s not within %s%% "
                        "of expected %s. (Python version %s)" % (
                        calls, (variance * 100), count, py_version))

                return result
            finally:
                if os.path.exists(filename):
                    os.unlink(filename)
        return function_named(counted, fn.__name__)
Example #6
0
def close_first(fn):
    """Decorator that closes all connections before fn execution."""
    def decorated(*args, **kw):
        testing_reaper.close_all()
        fn(*args, **kw)

    return function_named(decorated, fn.__name__)
    def decorator(fn):
        def profiled(*args, **kw):
            if (target not in profile_config['targets']
                    and not target_opts.get('always', None)):
                return fn(*args, **kw)

            elapsed, load_stats, result = _profile(filename, fn, *args, **kw)

            report = target_opts.get('report', profile_config['report'])
            if report:
                sort_ = target_opts.get('sort', profile_config['sort'])
                limit = target_opts.get('limit', profile_config['limit'])
                print "Profile report for target '%s' (%s)" % (target,
                                                               filename)

                stats = load_stats()
                stats.sort_stats(*sort_)
                if limit:
                    stats.print_stats(limit)
                else:
                    stats.print_stats()
                #stats.print_callers()
            os.unlink(filename)
            return result

        return function_named(profiled, fn.__name__)
Example #8
0
    def decorator(fn):
        def profiled(*args, **kw):
            if (target not in profile_config['targets'] and
                not target_opts.get('always', None)):
                return fn(*args, **kw)

            elapsed, load_stats, result = _profile(
                filename, fn, *args, **kw)

            report = target_opts.get('report', profile_config['report'])
            if report:
                sort_ = target_opts.get('sort', profile_config['sort'])
                limit = target_opts.get('limit', profile_config['limit'])
                print "Profile report for target '%s' (%s)" % (
                    target, filename)

                stats = load_stats()
                stats.sort_stats(*sort_)
                if limit:
                    stats.print_stats(limit)
                else:
                    stats.print_stats()
                #stats.print_callers()
            os.unlink(filename)
            return result
        return function_named(profiled, fn.__name__)
    def decorator(fn):
        def counted(*args, **kw):
            try:
                filename = "%s.prof" % fn.__name__

                elapsed, stat_loader, result = _profile(
                    filename, fn, *args, **kw)

                stats = stat_loader()
                calls = stats.total_calls

                stats.sort_stats('calls', 'cumulative')
                stats.print_stats()
                #stats.print_callers()
                deviance = int(count * variance)
                if (calls < (count - deviance) or calls > (count + deviance)):
                    raise AssertionError(
                        "Function call count %s not within %s%% "
                        "of expected %s. (Python version %s)" %
                        (calls, (variance * 100), count, py_version))

                return result
            finally:
                if os.path.exists(filename):
                    os.unlink(filename)

        return function_named(counted, fn.__name__)
Example #10
0
    def decorate(fn):
        def safe(*args, **kw):
            # todo: should probably be strict about this, too
            filters = [
                dict(action='ignore',
                     category=sa_exc.SAPendingDeprecationWarning)
            ]
            if not messages:
                filters.append(
                    dict(action='ignore',
                         category=sa_exc.SADeprecationWarning))
            else:
                filters.extend([
                    dict(action='ignore',
                         message=message,
                         category=sa_exc.SADeprecationWarning)
                    for message in [(m.startswith('//') and (
                        'Call to deprecated function ' + m[2:]) or m)
                                    for m in messages]
                ])

            for f in filters:
                warnings.filterwarnings(**f)
            try:
                return fn(*args, **kw)
            finally:
                resetwarnings()

        return function_named(safe, fn.__name__)
Example #11
0
def resolve_artifact_names(fn):
    """Decorator, augment function globals with tables and classes.

    Swaps out the function's globals at execution time. The 'global' statement
    will not work as expected inside a decorated function.

    """
    # This could be automatically applied to framework and test_ methods in
    # the MappedTest-derived test suites but... *some* explicitness for this
    # magic is probably good.  Especially as 'global' won't work- these
    # rebound functions aren't regular Python..
    #
    # Also: it's lame that CPython accepts a dict-subclass for globals, but
    # only calls dict methods.  That would allow 'global' to pass through to
    # the func_globals.
    def resolved(*args, **kwargs):
        self = args[0]
        context = dict(fn.func_globals)
        for source in self._artifact_registries:
            context.update(getattr(self, source))
        # jython bug #1034
        rebound = types.FunctionType(
            fn.func_code, context, fn.func_name, fn.func_defaults,
            fn.func_closure)
        return rebound(*args, **kwargs)
    return function_named(resolved, fn.func_name)
 def decorate(fn):
     def wrapped(*args, **kw):
         try:
             attributes._install_lookup_strategy(strategy)
             return fn(*args, **kw)
         finally:
             attributes._install_lookup_strategy(sa.util.symbol('native'))
     return function_named(wrapped, fn.func_name)
Example #13
0
def close_first(fn):
    """Decorator that closes all connections before fn execution."""

    def decorated(*args, **kw):
        testing_reaper.close_all()
        fn(*args, **kw)

    return function_named(decorated, fn.__name__)
Example #14
0
def close_open_connections(fn):
    """Decorator that closes all connections after fn execution."""

    def decorated(*args, **kw):
        try:
            fn(*args, **kw)
        finally:
            testing_reaper.close_all()
    return function_named(decorated, fn.__name__)
Example #15
0
def close_open_connections(fn):
    """Decorator that closes all connections after fn execution."""
    def decorated(*args, **kw):
        try:
            fn(*args, **kw)
        finally:
            testing_reaper.close_all()

    return function_named(decorated, fn.__name__)
Example #16
0
    def decorate(fn):
        def wrapped(*args, **kw):
            try:
                attributes._install_lookup_strategy(strategy)
                return fn(*args, **kw)
            finally:
                attributes._install_lookup_strategy(sa.util.symbol('native'))

        return function_named(wrapped, fn.func_name)
Example #17
0
    def decorator(fn):
        def at_runtime(*args, **kw):
            criteria = categories.get(discriminator(), None)
            if criteria is None:
                return fn(*args, **kw)

            rewrapped = function_call_count(*criteria)(fn)
            return rewrapped(*args, **kw)
        return function_named(at_runtime, fn.__name__)
Example #18
0
def rollback_open_connections(fn):
    """Decorator that rolls back all open connections after fn execution."""

    def decorated(*args, **kw):
        try:
            fn(*args, **kw)
        finally:
            testing_reaper.rollback_all()
    return function_named(decorated, fn.__name__)
Example #19
0
def rollback_open_connections(fn):
    """Decorator that rolls back all open connections after fn execution."""
    def decorated(*args, **kw):
        try:
            fn(*args, **kw)
        finally:
            testing_reaper.rollback_all()

    return function_named(decorated, fn.__name__)
def modifies_instrumentation_finders(fn):
    def decorated(*args, **kw):
        pristine = attributes.instrumentation_finders[:]
        try:
            fn(*args, **kw)
        finally:
            del attributes.instrumentation_finders[:]
            attributes.instrumentation_finders.extend(pristine)
    return function_named(decorated, fn.func_name)
Example #21
0
def modifies_instrumentation_finders(fn):
    def decorated(*args, **kw):
        pristine = attributes.instrumentation_finders[:]
        try:
            fn(*args, **kw)
        finally:
            del attributes.instrumentation_finders[:]
            attributes.instrumentation_finders.extend(pristine)

    return function_named(decorated, fn.func_name)
Example #22
0
 def decorate(fn):
     fn_name = fn.__name__
     def maybe(*args, **kw):
         if predicate():
             msg = "'%s' skipped on DB %s version '%s': %s" % (
                 fn_name, config.db.name, _server_version(), reason)
             raise SkipTest(msg)
         else:
             return fn(*args, **kw)
     return function_named(maybe, fn_name)
    def decorator(fn):
        def at_runtime(*args, **kw):
            criteria = categories.get(discriminator(), None)
            if criteria is None:
                return fn(*args, **kw)

            rewrapped = function_call_count(*criteria)(fn)
            return rewrapped(*args, **kw)

        return function_named(at_runtime, fn.__name__)
Example #24
0
 def decorate(fn):
     fn_name = fn.__name__
     def maybe(*args, **kw):
         if _is_excluded(db, op, spec):
             msg = "'%s' unsupported on DB %s version '%s': %s" % (
                 fn_name, config.db.name, _server_version(), reason)
             print msg
             if carp:
                 print >> sys.stderr, msg
             return True
         else:
             return fn(*args, **kw)
     return function_named(maybe, fn_name)
Example #25
0
    def decorate(fn):
        fn_name = fn.__name__

        def maybe(*args, **kw):
            if predicate():
                msg = "'%s' skipped on DB %s version '%s': %s" % (
                    fn_name, config.db.name, _server_version(), reason)
                print msg
                return True
            else:
                return fn(*args, **kw)

        return function_named(maybe, fn_name)
Example #26
0
 def decorate(fn):
     fn_name = fn.__name__
     def maybe(*args, **kw):
         if predicate():
             msg = "'%s' skipped on DB %s version '%s': %s" % (
                 fn_name, config.db.name, _server_version(), reason)
             print msg
             if carp:
                 print >> sys.stderr, msg
             return True
         else:
             return fn(*args, **kw)
     return function_named(maybe, fn_name)
Example #27
0
 def decorate(fn):
     fn_name = fn.__name__
     def maybe(*args, **kw):
         if config.db.name == db:
             msg = "'%s' unsupported on DB implementation '%s': %s" % (
                 fn_name, config.db.name, reason)
             print msg
             if carp:
                 print >> sys.stderr, msg
             return True
         else:
             return fn(*args, **kw)
     return function_named(maybe, fn_name)
Example #28
0
 def decorate(fn):
     fn_name = fn.__name__
     def maybe(*args, **kw):
         if _is_excluded(db, op, spec):
             msg = "'%s' unsupported on DB %s version '%s': %s" % (
                 fn_name, config.db.name, _server_version(), reason)
             print msg
             if carp:
                 print >> sys.stderr, msg
             return True
         else:
             return fn(*args, **kw)
     return function_named(maybe, fn_name)
Example #29
0
 def decorate(fn):
     fn_name = fn.__name__
     def maybe(*args, **kw):
         if spec(config.db):
             return fn(*args, **kw)
         else:
             msg = "'%s' unsupported on DB implementation '%s+%s': %s" % (
                 fn_name, config.db.name, config.db.driver, reason)
             print msg
             if carp:
                 print >> sys.stderr, msg
             return True
     return function_named(maybe, fn_name)
Example #30
0
 def decorate(fn):
     def maybe(*args, **kw):
         if isinstance(db, basestring):
             if not spec(config.db):
                 return fn(*args, **kw)
             else:
                 wrapped = emits_warning(*warnings)(fn)
                 return wrapped(*args, **kw)
         else:
             if not _is_excluded(*db):
                 return fn(*args, **kw)
             else:
                 wrapped = emits_warning(*warnings)(fn)
                 return wrapped(*args, **kw)
     return function_named(maybe, fn.__name__)
Example #31
0
 def decorate(fn):
     def maybe(*args, **kw):
         if isinstance(db, basestring):
             if config.db.name != db:
                 return fn(*args, **kw)
             else:
                 wrapped = emits_warning(*warnings)(fn)
                 return wrapped(*args, **kw)
         else:
             if not _is_excluded(*db):
                 return fn(*args, **kw)
             else:
                 wrapped = emits_warning(*warnings)(fn)
                 return wrapped(*args, **kw)
     return function_named(maybe, fn.__name__)
Example #32
0
def provide_metadata(fn):
    """Provides a bound MetaData object for a single test, 
    drops it afterwards."""
    def maybe(*args, **kw):
        metadata = schema.MetaData(db)
        context = dict(fn.func_globals)
        context['metadata'] = metadata
        # jython bug #1034
        rebound = types.FunctionType(
            fn.func_code, context, fn.func_name, fn.func_defaults,
            fn.func_closure)
        try:
            return rebound(*args, **kw)
        finally:
            metadata.drop_all()
    return function_named(maybe, fn.__name__)
Example #33
0
def provide_metadata(fn):
    """Provides a bound MetaData object for a single test, 
    drops it afterwards."""
    def maybe(*args, **kw):
        metadata = schema.MetaData(db)
        context = dict(fn.func_globals)
        context['metadata'] = metadata
        # jython bug #1034
        rebound = types.FunctionType(fn.func_code, context, fn.func_name,
                                     fn.func_defaults, fn.func_closure)
        try:
            return rebound(*args, **kw)
        finally:
            metadata.drop_all()

    return function_named(maybe, fn.__name__)
Example #34
0
def _create_backref_test(autoflush, saveuser):

    @testing.resolve_artifact_names
    def test_backref(self):
        mapper(User, users, properties={
            'addresses':dynamic_loader(mapper(Address, addresses), backref='user')
        })
        sess = create_session(autoflush=autoflush)

        u = User(name='buffy')

        a = Address(email_address='*****@*****.**')
        a.user = u

        if saveuser:
            sess.add(u)
        else:
            sess.add(a)

        if not autoflush:
            sess.flush()

        assert u in sess
        assert a in sess

        self.assert_(list(u.addresses) == [a])

        a.user = None
        if not autoflush:
            self.assert_(list(u.addresses) == [a])

        if not autoflush:
            sess.flush()
        self.assert_(list(u.addresses) == [])

    test_backref = function_named(
        test_backref, "test%s%s" % ((autoflush and "_autoflush" or ""),
                                    (saveuser and "_saveuser" or "_savead")))
    setattr(SessionTest, test_backref.__name__, test_backref)
    def make_test(fetchtype):
        def test_roundtrip(self):
            class A(_fixtures.Base):
                pass

            class B(A):
                pass

            class C(B):
                pass

            if fetchtype == 'union':
                abc = a.outerjoin(b).outerjoin(c)
                bc = a.join(b).outerjoin(c)
            else:
                abc = bc = None

            mapper(A,
                   a,
                   with_polymorphic=('*', abc),
                   polymorphic_on=a.c.type,
                   polymorphic_identity='a')
            mapper(B,
                   b,
                   with_polymorphic=('*', bc),
                   inherits=A,
                   polymorphic_identity='b')
            mapper(C, c, inherits=B, polymorphic_identity='c')

            a1 = A(adata='a1')
            b1 = B(bdata='b1', adata='b1')
            b2 = B(bdata='b2', adata='b2')
            b3 = B(bdata='b3', adata='b3')
            c1 = C(cdata='c1', bdata='c1', adata='c1')
            c2 = C(cdata='c2', bdata='c2', adata='c2')
            c3 = C(cdata='c2', bdata='c2', adata='c2')

            sess = create_session()
            for x in (a1, b1, b2, b3, c1, c2, c3):
                sess.add(x)
            sess.flush()
            sess.expunge_all()

            #for obj in sess.query(A).all():
            #    print obj
            assert [
                A(adata='a1'),
                B(bdata='b1', adata='b1'),
                B(bdata='b2', adata='b2'),
                B(bdata='b3', adata='b3'),
                C(cdata='c1', bdata='c1', adata='c1'),
                C(cdata='c2', bdata='c2', adata='c2'),
                C(cdata='c2', bdata='c2', adata='c2'),
            ] == sess.query(A).order_by(A.id).all()

            assert [
                B(bdata='b1', adata='b1'),
                B(bdata='b2', adata='b2'),
                B(bdata='b3', adata='b3'),
                C(cdata='c1', bdata='c1', adata='c1'),
                C(cdata='c2', bdata='c2', adata='c2'),
                C(cdata='c2', bdata='c2', adata='c2'),
            ] == sess.query(B).all()

            assert [
                C(cdata='c1', bdata='c1', adata='c1'),
                C(cdata='c2', bdata='c2', adata='c2'),
                C(cdata='c2', bdata='c2', adata='c2'),
            ] == sess.query(C).all()

        test_roundtrip = function_named(test_roundtrip, 'test_%s' % fetchtype)
        return test_roundtrip
Example #36
0
        fn_name = fn.__name__
        def maybe(*args, **kw):
            if not callable_():
                return fn(*args, **kw)
            else:
                try:
                    fn(*args, **kw)
                except Exception, ex:
                    print ("'%s' failed as expected (condition: %s): %s " % (
                        fn_name, description, str(ex)))
                    return True
                else:
                    raise AssertionError(
                        "Unexpected success for '%s' (condition: %s)" %
                        (fn_name, description))
        return function_named(maybe, fn_name)
    return decorate


def future(fn):
    """Mark a test as expected to unconditionally fail.

    Takes no arguments, omit parens when using as a decorator.
    """

    fn_name = fn.__name__
    def decorated(*args, **kw):
        try:
            fn(*args, **kw)
        except Exception, ex:
            print ("Future test '%s' failed as expected: %s " % (
Example #37
0
def _generate_test(jointype="join1", usedata=False):
    def do_test(self):
        class Person(AttrSettable):
            pass
        class Manager(Person):
            pass

        if usedata:
            class Data(object):
                def __init__(self, data):
                    self.data = data

        if jointype == "join1":
            poly_union = polymorphic_union({
                'manager':managers.join(people, people.c.person_id==managers.c.person_id),
                'person':people.select(people.c.type=='person')
            }, None)
        elif jointype =="join2":
            poly_union = polymorphic_union({
                'manager':join(people, managers, people.c.person_id==managers.c.person_id),
                'person':people.select(people.c.type=='person')
            }, None)
        elif jointype == 'join3':
            poly_union = people.outerjoin(managers)
        elif jointype == "join4":
            poly_union=None

        if usedata:
            mapper(Data, data)

        if usedata:
            mapper(Person, people, with_polymorphic=('*', poly_union), polymorphic_identity='person', polymorphic_on=people.c.type,
                  properties={
                    'colleagues':relation(Person, primaryjoin=people.c.colleague_id==people.c.person_id, remote_side=people.c.colleague_id, uselist=True),
                    'data':relation(Data, uselist=False)
                    }
            )
        else:
            mapper(Person, people, with_polymorphic=('*', poly_union), polymorphic_identity='person', polymorphic_on=people.c.type,
                  properties={
                    'colleagues':relation(Person, primaryjoin=people.c.colleague_id==people.c.person_id,
                        remote_side=people.c.colleague_id, uselist=True)
                    }
            )

        mapper(Manager, managers, inherits=Person, inherit_condition=people.c.person_id==managers.c.person_id, polymorphic_identity='manager')

        sess = create_session()
        p = Person(name='person1')
        p2 = Person(name='person2')
        p3 = Person(name='person3')
        m = Manager(name='manager1')
        p.colleagues.append(p2)
        m.colleagues.append(p3)
        if usedata:
            p.data = Data('ps data')
            m.data = Data('ms data')

        sess.add(m)
        sess.add(p)
        sess.flush()

        sess.expunge_all()
        p = sess.query(Person).get(p.person_id)
        p2 = sess.query(Person).get(p2.person_id)
        p3 = sess.query(Person).get(p3.person_id)
        m = sess.query(Person).get(m.person_id)
        print p, p2, p.colleagues, m.colleagues
        assert len(p.colleagues) == 1
        assert p.colleagues == [p2]
        assert m.colleagues == [p3]
        if usedata:
            assert p.data.data == 'ps data'
            assert m.data.data == 'ms data'

    do_test = function_named(
        do_test, 'test_relation_on_base_class_%s_%s' % (
        jointype, data and "nodata" or "data"))
    return do_test
Example #38
0
        def maybe(*args, **kw):
            if not callable_():
                return fn(*args, **kw)
            else:
                try:
                    fn(*args, **kw)
                except Exception, ex:
                    print("'%s' failed as expected (condition: %s): %s " %
                          (fn_name, description, str(ex)))
                    return True
                else:
                    raise AssertionError(
                        "Unexpected success for '%s' (condition: %s)" %
                        (fn_name, description))

        return function_named(maybe, fn_name)

    return decorate


def future(fn):
    """Mark a test as expected to unconditionally fail.

    Takes no arguments, omit parens when using as a decorator.
    """

    fn_name = fn.__name__

    def decorated(*args, **kw):
        try:
            fn(*args, **kw)
Example #39
0
def _generate_round_trip_test(include_base, lazy_relation, redefine_colprop, with_polymorphic):
    """generates a round trip test.

    include_base - whether or not to include the base 'person' type in the union.
    lazy_relation - whether or not the Company relation to People is lazy or eager.
    redefine_colprop - if we redefine the 'name' column to be 'people_name' on the base Person class
    use_literal_join - primary join condition is explicitly specified
    """
    def test_roundtrip(self):
        if with_polymorphic == 'unions':
            if include_base:
                person_join = polymorphic_union(
                    {
                        'engineer':people.join(engineers),
                        'manager':people.join(managers),
                        'person':people.select(people.c.type=='person'),
                    }, None, 'pjoin')
            else:
                person_join = polymorphic_union(
                    {
                        'engineer':people.join(engineers),
                        'manager':people.join(managers),
                    }, None, 'pjoin')
                
            manager_join = people.join(managers).outerjoin(boss)
            person_with_polymorphic = ['*', person_join]
            manager_with_polymorphic = ['*', manager_join]
        elif with_polymorphic == 'joins':
            person_join = people.outerjoin(engineers).outerjoin(managers).outerjoin(boss)
            manager_join = people.join(managers).outerjoin(boss)
            person_with_polymorphic = ['*', person_join]
            manager_with_polymorphic = ['*', manager_join]
        elif with_polymorphic == 'auto':
            person_with_polymorphic = '*'
            manager_with_polymorphic = '*'
        else:
            person_with_polymorphic = None
            manager_with_polymorphic = None

        if redefine_colprop:
            person_mapper = mapper(Person, people, with_polymorphic=person_with_polymorphic, polymorphic_on=people.c.type, polymorphic_identity='person', properties= {'person_name':people.c.name})
        else:
            person_mapper = mapper(Person, people, with_polymorphic=person_with_polymorphic, polymorphic_on=people.c.type, polymorphic_identity='person')

        mapper(Engineer, engineers, inherits=person_mapper, polymorphic_identity='engineer')
        mapper(Manager, managers, inherits=person_mapper, with_polymorphic=manager_with_polymorphic, polymorphic_identity='manager')

        mapper(Boss, boss, inherits=Manager, polymorphic_identity='boss')

        mapper(Company, companies, properties={
            'employees': relation(Person, lazy=lazy_relation,
                                  cascade="all, delete-orphan",
            backref="company", order_by=people.c.person_id
            )
        })

        if redefine_colprop:
            person_attribute_name = 'person_name'
        else:
            person_attribute_name = 'name'

        employees = [
                Manager(status='AAB', manager_name='manager1', **{person_attribute_name:'pointy haired boss'}),
                Engineer(status='BBA', engineer_name='engineer1', primary_language='java', **{person_attribute_name:'dilbert'}),
            ]
        if include_base:
            employees.append(Person(**{person_attribute_name:'joesmith'}))
        employees += [
            Engineer(status='CGG', engineer_name='engineer2', primary_language='python', **{person_attribute_name:'wally'}),
            Manager(status='ABA', manager_name='manager2', **{person_attribute_name:'jsmith'})
        ]
        
        pointy = employees[0]
        jsmith = employees[-1]
        dilbert = employees[1]
        
        session = create_session()
        c = Company(name='company1')
        c.employees = employees
        session.add(c)

        session.flush()
        session.expunge_all()
        
        eq_(session.query(Person).get(dilbert.person_id), dilbert)
        session.expunge_all()

        eq_(session.query(Person).filter(Person.person_id==dilbert.person_id).one(), dilbert)
        session.expunge_all()

        def go():
            cc = session.query(Company).get(c.company_id)
            eq_(cc.employees, employees)
            
        if not lazy_relation:
            if with_polymorphic != 'none':
                self.assert_sql_count(testing.db, go, 1)
            else:
                self.assert_sql_count(testing.db, go, 5)

        else:
            if with_polymorphic != 'none':
                self.assert_sql_count(testing.db, go, 2)
            else:
                self.assert_sql_count(testing.db, go, 6)
        
        # test selecting from the query, using the base mapped table (people) as the selection criterion.
        # in the case of the polymorphic Person query, the "people" selectable should be adapted to be "person_join"
        eq_(
            session.query(Person).filter(getattr(Person, person_attribute_name)=='dilbert').first(),
            dilbert
        )

        assert session.query(Person).filter(getattr(Person, person_attribute_name)=='dilbert').first().person_id

        eq_(
            session.query(Engineer).filter(getattr(Person, person_attribute_name)=='dilbert').first(),
            dilbert
        )
        
        # test selecting from the query, joining against an alias of the base "people" table.  test that
        # the "palias" alias does *not* get sucked up into the "person_join" conversion.
        palias = people.alias("palias")
        dilbert = session.query(Person).get(dilbert.person_id)
        assert dilbert is session.query(Person).filter((palias.c.name=='dilbert') & (palias.c.person_id==Person.person_id)).first()
        assert dilbert is session.query(Engineer).filter((palias.c.name=='dilbert') & (palias.c.person_id==Person.person_id)).first()
        assert dilbert is session.query(Person).filter((Engineer.engineer_name=="engineer1") & (engineers.c.person_id==people.c.person_id)).first()
        assert dilbert is session.query(Engineer).filter(Engineer.engineer_name=="engineer1")[0]
        
        dilbert.engineer_name = 'hes dibert!'

        session.flush()
        session.expunge_all()
        
        def go():
            session.query(Person).filter(getattr(Person, person_attribute_name)=='dilbert').first()
        self.assert_sql_count(testing.db, go, 1)
        session.expunge_all()
        dilbert = session.query(Person).filter(getattr(Person, person_attribute_name)=='dilbert').first()
        def go():
            # assert that only primary table is queried for already-present-in-session
            d = session.query(Person).filter(getattr(Person, person_attribute_name)=='dilbert').first()
        self.assert_sql_count(testing.db, go, 1)

        # test standalone orphans
        daboss = Boss(status='BBB', manager_name='boss', golf_swing='fore', **{person_attribute_name:'daboss'})
        session.add(daboss)
        assert_raises(orm_exc.FlushError, session.flush)
        c = session.query(Company).first()
        daboss.company = c
        manager_list = [e for e in c.employees if isinstance(e, Manager)]
        session.flush()
        session.expunge_all()

        eq_(session.query(Manager).order_by(Manager.person_id).all(), manager_list)
        c = session.query(Company).first()
        
        session.delete(c)
        session.flush()
        
        eq_(people.count().scalar(), 0)
        
    test_roundtrip = function_named(
        test_roundtrip, "test_%s%s%s_%s" % (
          (lazy_relation and "lazy" or "eager"),
          (include_base and "_inclbase" or ""),
          (redefine_colprop and "_redefcol" or ""),
          with_polymorphic))
    setattr(RoundTripTest, test_roundtrip.__name__, test_roundtrip)
Example #40
0
def _generate_test(jointype="join1", usedata=False):
    def do_test(self):
        class Person(AttrSettable):
            pass
        class Manager(Person):
            pass

        if usedata:
            class Data(object):
                def __init__(self, data):
                    self.data = data

        if jointype == "join1":
            poly_union = polymorphic_union({
                'manager':managers.join(people, people.c.person_id==managers.c.person_id),
                'person':people.select(people.c.type=='person')
            }, None)
        elif jointype =="join2":
            poly_union = polymorphic_union({
                'manager':join(people, managers, people.c.person_id==managers.c.person_id),
                'person':people.select(people.c.type=='person')
            }, None)
        elif jointype == 'join3':
            poly_union = people.outerjoin(managers)
        elif jointype == "join4":
            poly_union=None

        if usedata:
            mapper(Data, data)

        if usedata:
            mapper(Person, people, with_polymorphic=('*', poly_union), polymorphic_identity='person', polymorphic_on=people.c.type,
                  properties={
                    'colleagues':relation(Person, primaryjoin=people.c.colleague_id==people.c.person_id, remote_side=people.c.colleague_id, uselist=True),
                    'data':relation(Data, uselist=False)
                    }
            )
        else:
            mapper(Person, people, with_polymorphic=('*', poly_union), polymorphic_identity='person', polymorphic_on=people.c.type,
                  properties={
                    'colleagues':relation(Person, primaryjoin=people.c.colleague_id==people.c.person_id,
                        remote_side=people.c.colleague_id, uselist=True)
                    }
            )

        mapper(Manager, managers, inherits=Person, inherit_condition=people.c.person_id==managers.c.person_id, polymorphic_identity='manager')

        sess = create_session()
        p = Person(name='person1')
        p2 = Person(name='person2')
        p3 = Person(name='person3')
        m = Manager(name='manager1')
        p.colleagues.append(p2)
        m.colleagues.append(p3)
        if usedata:
            p.data = Data('ps data')
            m.data = Data('ms data')

        sess.add(m)
        sess.add(p)
        sess.flush()

        sess.expunge_all()
        p = sess.query(Person).get(p.person_id)
        p2 = sess.query(Person).get(p2.person_id)
        p3 = sess.query(Person).get(p3.person_id)
        m = sess.query(Person).get(m.person_id)
        print p, p2, p.colleagues, m.colleagues
        assert len(p.colleagues) == 1
        assert p.colleagues == [p2]
        assert m.colleagues == [p3]
        if usedata:
            assert p.data.data == 'ps data'
            assert m.data.data == 'ms data'

    do_test = function_named(
        do_test, 'test_relation_on_base_class_%s_%s' % (
        jointype, data and "nodata" or "data"))
    return do_test
Example #41
0
def generate_round_trip_test(use_unions=False, use_joins=False):
    def test_roundtrip(self):
        publication_mapper = mapper(Publication, publication_table)

        issue_mapper = mapper(Issue, issue_table, properties = {
            'publication': relationship(Publication, backref=backref('issues', cascade="all, delete-orphan")),
        })

        location_name_mapper = mapper(LocationName, location_name_table)

        location_mapper = mapper(Location, location_table, properties = {
            'issue': relationship(Issue, backref=backref('locations', lazy='joined', cascade="all, delete-orphan")),
            '_name': relationship(LocationName),
        })

        page_size_mapper = mapper(PageSize, page_size_table)

        magazine_mapper = mapper(Magazine, magazine_table, properties = {
            'location': relationship(Location, backref=backref('magazine', uselist=False)),
            'size': relationship(PageSize),
        })

        if use_unions:
            page_join = polymorphic_union(
                {
                    'm': page_table.join(magazine_page_table),
                    'c': page_table.join(magazine_page_table).join(classified_page_table),
                    'p': page_table.select(page_table.c.type=='p'),
                }, None, 'page_join')
            page_mapper = mapper(Page, page_table, with_polymorphic=('*', page_join), polymorphic_on=page_join.c.type, polymorphic_identity='p')
        elif use_joins:
            page_join = page_table.outerjoin(magazine_page_table).outerjoin(classified_page_table)
            page_mapper = mapper(Page, page_table, with_polymorphic=('*', page_join), polymorphic_on=page_table.c.type, polymorphic_identity='p')
        else:
            page_mapper = mapper(Page, page_table, polymorphic_on=page_table.c.type, polymorphic_identity='p')

        if use_unions:
            magazine_join = polymorphic_union(
                {
                    'm': page_table.join(magazine_page_table),
                    'c': page_table.join(magazine_page_table).join(classified_page_table),
                }, None, 'page_join')
            magazine_page_mapper = mapper(MagazinePage, magazine_page_table, with_polymorphic=('*', magazine_join), inherits=page_mapper, polymorphic_identity='m', properties={
                'magazine': relationship(Magazine, backref=backref('pages', order_by=magazine_join.c.page_no))
            })
        elif use_joins:
            magazine_join = page_table.join(magazine_page_table).outerjoin(classified_page_table)
            magazine_page_mapper = mapper(MagazinePage, magazine_page_table, with_polymorphic=('*', magazine_join), inherits=page_mapper, polymorphic_identity='m', properties={
                'magazine': relationship(Magazine, backref=backref('pages', order_by=page_table.c.page_no))
            })
        else:
            magazine_page_mapper = mapper(MagazinePage, magazine_page_table, inherits=page_mapper, polymorphic_identity='m', properties={
                'magazine': relationship(Magazine, backref=backref('pages', order_by=page_table.c.page_no))
            })

        classified_page_mapper = mapper(ClassifiedPage, 
                                    classified_page_table, 
                                    inherits=magazine_page_mapper, 
                                    polymorphic_identity='c', 
                                    primary_key=[page_table.c.id])


        session = create_session()

        pub = Publication(name='Test')
        issue = Issue(issue=46,publication=pub)

        location = Location(ref='ABC',name='London',issue=issue)

        page_size = PageSize(name='A4',width=210,height=297)

        magazine = Magazine(location=location,size=page_size)
        page = ClassifiedPage(magazine=magazine,page_no=1)
        page2 = MagazinePage(magazine=magazine,page_no=2)
        page3 = ClassifiedPage(magazine=magazine,page_no=3)
        session.add(pub)

        session.flush()
        print [x for x in session]
        session.expunge_all()

        session.flush()
        session.expunge_all()
        p = session.query(Publication).filter(Publication.name=="Test").one()

        print p.issues[0].locations[0].magazine.pages
        print [page, page2, page3]
        assert repr(p.issues[0].locations[0].magazine.pages) == repr([page, page2, page3]), repr(p.issues[0].locations[0].magazine.pages)

    test_roundtrip = function_named(
        test_roundtrip, "test_%s" % (not use_union and (use_joins and "joins" or "select") or "unions"))
    setattr(MagazineTest, test_roundtrip.__name__, test_roundtrip)
Example #42
0
    def _create_test(polymorphic, name):
        def test_get(self):
            class Foo(object):
                pass

            class Bar(Foo):
                pass

            class Blub(Bar):
                pass

            if polymorphic:
                mapper(Foo, foo, polymorphic_on=foo.c.type, polymorphic_identity="foo")
                mapper(Bar, bar, inherits=Foo, polymorphic_identity="bar")
                mapper(Blub, blub, inherits=Bar, polymorphic_identity="blub")
            else:
                mapper(Foo, foo)
                mapper(Bar, bar, inherits=Foo)
                mapper(Blub, blub, inherits=Bar)

            sess = create_session()
            f = Foo()
            b = Bar()
            bl = Blub()
            sess.add(f)
            sess.add(b)
            sess.add(bl)
            sess.flush()

            if polymorphic:

                def go():
                    assert sess.query(Foo).get(f.id) == f
                    assert sess.query(Foo).get(b.id) == b
                    assert sess.query(Foo).get(bl.id) == bl
                    assert sess.query(Bar).get(b.id) == b
                    assert sess.query(Bar).get(bl.id) == bl
                    assert sess.query(Blub).get(bl.id) == bl

                self.assert_sql_count(testing.db, go, 0)
            else:
                # this is testing the 'wrong' behavior of using get()
                # polymorphically with mappers that are not configured to be
                # polymorphic.  the important part being that get() always
                # returns an instance of the query's type.
                def go():
                    assert sess.query(Foo).get(f.id) == f

                    bb = sess.query(Foo).get(b.id)
                    assert isinstance(b, Foo) and bb.id == b.id

                    bll = sess.query(Foo).get(bl.id)
                    assert isinstance(bll, Foo) and bll.id == bl.id

                    assert sess.query(Bar).get(b.id) == b

                    bll = sess.query(Bar).get(bl.id)
                    assert isinstance(bll, Bar) and bll.id == bl.id

                    assert sess.query(Blub).get(bl.id) == bl

                self.assert_sql_count(testing.db, go, 3)

        test_get = function_named(test_get, name)
        return test_get
Example #43
0
def _generate_round_trip_test(include_base, lazy_relation, redefine_colprop,
                              with_polymorphic):
    """generates a round trip test.

    include_base - whether or not to include the base 'person' type in the union.
    lazy_relation - whether or not the Company relation to People is lazy or eager.
    redefine_colprop - if we redefine the 'name' column to be 'people_name' on the base Person class
    use_literal_join - primary join condition is explicitly specified
    """
    def test_roundtrip(self):
        if with_polymorphic == 'unions':
            if include_base:
                person_join = polymorphic_union(
                    {
                        'engineer': people.join(engineers),
                        'manager': people.join(managers),
                        'person': people.select(people.c.type == 'person'),
                    }, None, 'pjoin')
            else:
                person_join = polymorphic_union(
                    {
                        'engineer': people.join(engineers),
                        'manager': people.join(managers),
                    }, None, 'pjoin')

            manager_join = people.join(managers).outerjoin(boss)
            person_with_polymorphic = ['*', person_join]
            manager_with_polymorphic = ['*', manager_join]
        elif with_polymorphic == 'joins':
            person_join = people.outerjoin(engineers).outerjoin(
                managers).outerjoin(boss)
            manager_join = people.join(managers).outerjoin(boss)
            person_with_polymorphic = ['*', person_join]
            manager_with_polymorphic = ['*', manager_join]
        elif with_polymorphic == 'auto':
            person_with_polymorphic = '*'
            manager_with_polymorphic = '*'
        else:
            person_with_polymorphic = None
            manager_with_polymorphic = None

        if redefine_colprop:
            person_mapper = mapper(Person,
                                   people,
                                   with_polymorphic=person_with_polymorphic,
                                   polymorphic_on=people.c.type,
                                   polymorphic_identity='person',
                                   properties={'person_name': people.c.name})
        else:
            person_mapper = mapper(Person,
                                   people,
                                   with_polymorphic=person_with_polymorphic,
                                   polymorphic_on=people.c.type,
                                   polymorphic_identity='person')

        mapper(Engineer,
               engineers,
               inherits=person_mapper,
               polymorphic_identity='engineer')
        mapper(Manager,
               managers,
               inherits=person_mapper,
               with_polymorphic=manager_with_polymorphic,
               polymorphic_identity='manager')

        mapper(Boss, boss, inherits=Manager, polymorphic_identity='boss')

        mapper(Company,
               companies,
               properties={
                   'employees':
                   relation(Person,
                            lazy=lazy_relation,
                            cascade="all, delete-orphan",
                            backref="company",
                            order_by=people.c.person_id)
               })

        if redefine_colprop:
            person_attribute_name = 'person_name'
        else:
            person_attribute_name = 'name'

        employees = [
            Manager(status='AAB',
                    manager_name='manager1',
                    **{person_attribute_name: 'pointy haired boss'}),
            Engineer(status='BBA',
                     engineer_name='engineer1',
                     primary_language='java',
                     **{person_attribute_name: 'dilbert'}),
        ]
        if include_base:
            employees.append(Person(**{person_attribute_name: 'joesmith'}))
        employees += [
            Engineer(status='CGG',
                     engineer_name='engineer2',
                     primary_language='python',
                     **{person_attribute_name: 'wally'}),
            Manager(status='ABA',
                    manager_name='manager2',
                    **{person_attribute_name: 'jsmith'})
        ]

        pointy = employees[0]
        jsmith = employees[-1]
        dilbert = employees[1]

        session = create_session()
        c = Company(name='company1')
        c.employees = employees
        session.add(c)

        session.flush()
        session.expunge_all()

        eq_(session.query(Person).get(dilbert.person_id), dilbert)
        session.expunge_all()

        eq_(
            session.query(Person).filter(
                Person.person_id == dilbert.person_id).one(), dilbert)
        session.expunge_all()

        def go():
            cc = session.query(Company).get(c.company_id)
            eq_(cc.employees, employees)

        if not lazy_relation:
            if with_polymorphic != 'none':
                self.assert_sql_count(testing.db, go, 1)
            else:
                self.assert_sql_count(testing.db, go, 5)

        else:
            if with_polymorphic != 'none':
                self.assert_sql_count(testing.db, go, 2)
            else:
                self.assert_sql_count(testing.db, go, 6)

        # test selecting from the query, using the base mapped table (people) as the selection criterion.
        # in the case of the polymorphic Person query, the "people" selectable should be adapted to be "person_join"
        eq_(
            session.query(Person).filter(
                getattr(Person, person_attribute_name) == 'dilbert').first(),
            dilbert)

        assert session.query(Person).filter(
            getattr(Person, person_attribute_name) ==
            'dilbert').first().person_id

        eq_(
            session.query(Engineer).filter(
                getattr(Person, person_attribute_name) == 'dilbert').first(),
            dilbert)

        # test selecting from the query, joining against an alias of the base "people" table.  test that
        # the "palias" alias does *not* get sucked up into the "person_join" conversion.
        palias = people.alias("palias")
        dilbert = session.query(Person).get(dilbert.person_id)
        assert dilbert is session.query(Person).filter(
            (palias.c.name == 'dilbert')
            & (palias.c.person_id == Person.person_id)).first()
        assert dilbert is session.query(Engineer).filter(
            (palias.c.name == 'dilbert')
            & (palias.c.person_id == Person.person_id)).first()
        assert dilbert is session.query(Person).filter(
            (Engineer.engineer_name == "engineer1")
            & (engineers.c.person_id == people.c.person_id)).first()
        assert dilbert is session.query(Engineer).filter(
            Engineer.engineer_name == "engineer1")[0]

        dilbert.engineer_name = 'hes dibert!'

        session.flush()
        session.expunge_all()

        def go():
            session.query(Person).filter(
                getattr(Person, person_attribute_name) == 'dilbert').first()

        self.assert_sql_count(testing.db, go, 1)
        session.expunge_all()
        dilbert = session.query(Person).filter(
            getattr(Person, person_attribute_name) == 'dilbert').first()

        def go():
            # assert that only primary table is queried for already-present-in-session
            d = session.query(Person).filter(
                getattr(Person, person_attribute_name) == 'dilbert').first()

        self.assert_sql_count(testing.db, go, 1)

        # test standalone orphans
        daboss = Boss(status='BBB',
                      manager_name='boss',
                      golf_swing='fore',
                      **{person_attribute_name: 'daboss'})
        session.add(daboss)
        assert_raises(orm_exc.FlushError, session.flush)
        c = session.query(Company).first()
        daboss.company = c
        manager_list = [e for e in c.employees if isinstance(e, Manager)]
        session.flush()
        session.expunge_all()

        eq_(
            session.query(Manager).order_by(Manager.person_id).all(),
            manager_list)
        c = session.query(Company).first()

        session.delete(c)
        session.flush()

        eq_(people.count().scalar(), 0)

    test_roundtrip = function_named(
        test_roundtrip, "test_%s%s%s_%s" %
        ((lazy_relation and "lazy" or "eager"),
         (include_base and "_inclbase" or ""),
         (redefine_colprop and "_redefcol" or ""), with_polymorphic))
    setattr(RoundTripTest, test_roundtrip.__name__, test_roundtrip)
Example #44
0
        location = Location(ref='ABC',name='London',issue=issue)

        page_size = PageSize(name='A4',width=210,height=297)

        magazine = Magazine(location=location,size=page_size)
        page = ClassifiedPage(magazine=magazine,page_no=1)
        page2 = MagazinePage(magazine=magazine,page_no=2)
        page3 = ClassifiedPage(magazine=magazine,page_no=3)
        session.add(pub)

        session.flush()
        print [x for x in session]
        session.expunge_all()

        session.flush()
        session.expunge_all()
        p = session.query(Publication).filter(Publication.name=="Test").one()

        print p.issues[0].locations[0].magazine.pages
        print [page, page2, page3]
        assert repr(p.issues[0].locations[0].magazine.pages) == repr([page, page2, page3]), repr(p.issues[0].locations[0].magazine.pages)

    test_roundtrip = function_named(
        test_roundtrip, "test_%s" % (not use_union and (use_joins and "joins" or "select") or "unions"))
    setattr(MagazineTest, test_roundtrip.__name__, test_roundtrip)

for (use_union, use_join) in [(True, False), (False, True), (False, False)]:
    generate_round_trip_test(use_union, use_join)


Example #45
0
    def _create_test(polymorphic, name):
        def test_get(self):
            class Foo(object):
                pass

            class Bar(Foo):
                pass

            class Blub(Bar):
                pass

            if polymorphic:
                mapper(Foo, foo, polymorphic_on=foo.c.type, polymorphic_identity='foo')
                mapper(Bar, bar, inherits=Foo, polymorphic_identity='bar')
                mapper(Blub, blub, inherits=Bar, polymorphic_identity='blub')
            else:
                mapper(Foo, foo)
                mapper(Bar, bar, inherits=Foo)
                mapper(Blub, blub, inherits=Bar)

            sess = create_session()
            f = Foo()
            b = Bar()
            bl = Blub()
            sess.add(f)
            sess.add(b)
            sess.add(bl)
            sess.flush()

            if polymorphic:
                def go():
                    assert sess.query(Foo).get(f.id) == f
                    assert sess.query(Foo).get(b.id) == b
                    assert sess.query(Foo).get(bl.id) == bl
                    assert sess.query(Bar).get(b.id) == b
                    assert sess.query(Bar).get(bl.id) == bl
                    assert sess.query(Blub).get(bl.id) == bl

                self.assert_sql_count(testing.db, go, 0)
            else:
                # this is testing the 'wrong' behavior of using get()
                # polymorphically with mappers that are not configured to be
                # polymorphic.  the important part being that get() always
                # returns an instance of the query's type.
                def go():
                    assert sess.query(Foo).get(f.id) == f

                    bb = sess.query(Foo).get(b.id)
                    assert isinstance(b, Foo) and bb.id==b.id

                    bll = sess.query(Foo).get(bl.id)
                    assert isinstance(bll, Foo) and bll.id==bl.id

                    assert sess.query(Bar).get(b.id) == b

                    bll = sess.query(Bar).get(bl.id)
                    assert isinstance(bll, Bar) and bll.id == bl.id

                    assert sess.query(Blub).get(bl.id) == bl

                self.assert_sql_count(testing.db, go, 3)

        test_get = function_named(test_get, name)
        return test_get