コード例 #1
0
ファイル: tests.py プロジェクト: evo-company/sqlconstruct
    def test_many_to_many(self):
        ab_table = Table('a_b', self.base_cls.metadata,
                         Column('a_id', Integer, ForeignKey('a.id')),
                         Column('b_id', Integer, ForeignKey('b.id')))

        class A(self.base_cls):
            name = Column(String)
            b_list = relationship('B', secondary=ab_table)

        class B(self.base_cls):
            name = Column(String)
            a_list = relationship('A', secondary=ab_table)

        session = self.init()
        a1, a2, a3, a4 = A(name='a1'), A(name='a2'), A(name='a3'), A(name='a4')
        b1, b2, b3, b4 = B(name='b1'), B(name='b2'), B(name='b3'), B(name='b4')
        a1.b_list = [b2, b3, b4]
        a2.b_list = [b1, b3, b4]
        a3.b_list = [b1, b2, b4]
        a4.b_list = [b1, b2, b3]
        session.add_all([a1, a2, a3, a4])
        session.commit()

        q1 = (ConstructQuery({
            'a_name':
            A.name,
            'b_names':
            map_(apply_(capitalize, [B.name]), A.b_list),
        }).with_session(session.registry()).order_by(A.name))
        self.assertEqual(
            tuple((obj.a_name, set(obj.b_names)) for obj in q1.all()), (
                ('a1', {'B2', 'B3', 'B4'}),
                ('a2', {'B1', 'B3', 'B4'}),
                ('a3', {'B1', 'B2', 'B4'}),
                ('a4', {'B1', 'B2', 'B3'}),
            ))

        q2 = (ConstructQuery({
            'b_name':
            B.name,
            'a_names':
            map_(apply_(capitalize, [A.name]), B.a_list),
        }).with_session(session.registry()).order_by(B.name))
        self.assertEqual(
            tuple((obj.b_name, set(obj.a_names)) for obj in q2.all()),
            (
                ('b1', {'A2', 'A3', 'A4'}),
                ('b2', {'A1', 'A3', 'A4'}),
                ('b3', {'A1', 'A2', 'A4'}),
                ('b4', {'A1', 'A2', 'A3'}),
            ),
        )
コード例 #2
0
ファイル: tests.py プロジェクト: vmagamedov/sqlconstruct
    def test_one_to_many(self):

        class A(self.base_cls):
            name = Column(String)
            b_list = relationship('B')

            @hybrid_property
            def just_b_list(self):
                return self.b_list

        class B(self.base_cls):
            name = Column(String)
            a_id = Column(Integer, ForeignKey('a.id'))

        session = self.init()
        session.add_all([
            A(name='a1', b_list=[B(name='b1'), B(name='b2'), B(name='b3')]),
            A(name='a2', b_list=[B(name='b4'), B(name='b5'), B(name='b6')]),
            A(name='a3', b_list=[B(name='b7'), B(name='b8'), B(name='b9')]),
        ])
        session.commit()

        query = (
            ConstructQuery({
                'a_name': A.name,
                'b_names': map_(apply_(capitalize, [B.name]), A.b_list),
            })
            .with_session(session.registry())
        )
        self.assertEqual(
            tuple(dict(obj) for obj in query.all()),
            ({'a_name': 'a1', 'b_names': ['B1', 'B2', 'B3']},
             {'a_name': 'a2', 'b_names': ['B4', 'B5', 'B6']},
             {'a_name': 'a3', 'b_names': ['B7', 'B8', 'B9']}),
        )

        query = (
            ConstructQuery({
                'a_name': A.name,
                'b_names': map_(apply_(capitalize, [B.name]), A.just_b_list),
            })
            .with_session(session.registry())
        )
        self.assertEqual(
            tuple(dict(obj) for obj in query.all()),
            ({'a_name': 'a1', 'b_names': ['B1', 'B2', 'B3']},
             {'a_name': 'a2', 'b_names': ['B4', 'B5', 'B6']},
             {'a_name': 'a3', 'b_names': ['B7', 'B8', 'B9']}),
        )
コード例 #3
0
ファイル: tests.py プロジェクト: uvNikita/sqlconstruct
    def test_one_to_one(self):

        class A(self.base_cls):
            name = Column(String)
            b = relationship('B', uselist=False)

        class B(self.base_cls):
            name = Column(String)
            a_id = Column(Integer, ForeignKey('a.id'))

        session = self.init()
        session.add_all([
            A(name='a1', b=B(name='b1')),
            A(name='a2'),
            B(name='b2'),
            A(name='a3', b=B(name='b3')),
        ])
        session.commit()

        query = (
            ConstructQuery({
                'a_name': A.name,
                'b_name': get_(if_(B.id, apply_(capitalize, [B.name]), '~'),
                               A.b),
            })
            .with_session(session.registry())
        )
        self.assertEqual(
            tuple(dict(obj) for obj in query.all()),
            ({'a_name': 'a1', 'b_name': 'B1'},
             {'a_name': 'a2', 'b_name': '~'},
             {'a_name': 'a3', 'b_name': 'B3'}),
        )
コード例 #4
0
ファイル: tests.py プロジェクト: alafin/sqlconstruct
    def test_defined_calls(self):
        c1 = self.a_cls.__table__.c.id
        c2 = self.a_cls.__table__.c.name
        c3 = self.b_cls.__table__.c.id
        c4 = self.b_cls.__table__.c.name

        self.assertEqual(
            defined_func(self.a_cls(id=1, name='foo'),
                         self.b_cls(id=2, name='bar'),
                         extra_id=3,
                         extra_name='baz'),
            (1 + 2 + 3, 'foo' + 'bar' + 'baz'),
        )

        apl1 = defined_func.defn(self.a_cls, self.b_cls,
                                 extra_id=3, extra_name='baz')
        self.assertTrue(isinstance(apl1, apply_), type(apl1))
        self.assertEquals(columns_set(apl1), {c1, c2, c3, c4})
        self.assertEqual(
            proceed(apl1, {c1: 1, c2: 'foo', c3: 2, c4: 'bar'}),
            (1 + 2 + 3, 'foo' + 'bar' + 'baz'),
        )

        apl2 = defined_func.defn(self.a_cls, self.b_cls,
                                 extra_id=c1, extra_name=c2)
        self.assertTrue(isinstance(apl2, apply_), type(apl2))
        self.assertEquals(columns_set(apl2), {c1, c2, c3, c4})
        self.assertEqual(
            proceed(apl2, {c1: 1, c2: 'foo', c3: 2, c4: 'bar'}),
            (1 + 2 + 1, 'foo' + 'bar' + 'foo'),
        )

        apl3 = defined_func.defn(self.a_cls, self.b_cls,
                                 extra_id=apply_(operator.add, [c1, c3]),
                                 extra_name=apply_(operator.concat, [c2, c4]))
        self.assertTrue(isinstance(apl3, apply_), type(apl3))
        self.assertEquals(columns_set(apl3), {c1, c2, c3, c4})
        self.assertEqual(
            proceed(apl3, {c1: 1, c2: 'foo', c3: 2, c4: 'bar'}),
            (1 + 2 + (1 + 2), 'foo' + 'bar' + ('foo' + 'bar')),
        )

        self.assertEqual(
            defined_func.func(1, 'foo', 2, 'bar', 3, 'baz'),
            (1 + 2 + 3, 'foo' + 'bar' + 'baz'),
        )
コード例 #5
0
ファイル: tests.py プロジェクト: uvNikita/sqlconstruct
 def test_nested_construct(self):
     struct = Construct({
         'a_id': apply_(operator.add, [self.a_cls.id, 5]),
         'a_name': apply_(operator.concat, [self.a_cls.name, '-test']),
     })
     self.assertEqual(set(struct._columns), {
         self.a_cls.__table__.c.id,
         self.a_cls.__table__.c.name,
     })
     result = {
         self.a_cls.__table__.c.id: 1,
         self.a_cls.__table__.c.name: 'a1',
     }
     row = [result[col] for col in struct._columns]
     s = struct._from_row(row)
     self.assertEqual(s.a_id, 1 + 5)
     self.assertEqual(s.a_name, 'a1' + '-test')
コード例 #6
0
ファイル: tests.py プロジェクト: evo-company/sqlconstruct
    def test_nested_apply(self):
        c1 = self.a_cls.__table__.c.id
        c2 = self.b_cls.__table__.c.id

        add = lambda a, b: a + b

        apl = apply_(
            add,
            [
                apply_(
                    add,
                    [
                        apply_(add, [
                            0,
                            1,
                        ]),
                        apply_(
                            add,
                            [
                                2,
                                apply_(
                                    add,
                                    [
                                        3,
                                        c1,  # 4
                                    ]),
                            ]),
                    ]),
                apply_(
                    add,
                    [
                        apply_(
                            add,
                            [
                                apply_(
                                    add,
                                    [
                                        c2,  # 5
                                        6,
                                    ]),
                                7,
                            ]),
                        apply_(add, [
                            8,
                            9,
                        ]),
                    ]),
            ])
        self.assertEqual(columns_set(apl), {c1, c2})
        self.assertEqual(proceed(apl, {c1: 4, c2: 5}), sum(range(10)))
コード例 #7
0
ファイル: tests.py プロジェクト: uvNikita/sqlconstruct
    def test_pipe_operator(self):
        struct = Construct({
            'a_name_hash': apply_(capitalize, [self.a_cls.name]) | hash,
        })

        s1, s2 = self.session.query(struct).order_by(self.a_cls.name).all()

        self.assertEqual(s1.a_name_hash, hash('A1'))
        self.assertEqual(s2.a_name_hash, hash('A2'))
コード例 #8
0
ファイル: tests.py プロジェクト: evo-company/sqlconstruct
 def test_nested_construct(self):
     struct = Construct({
         'a_id':
         apply_(operator.add, [self.a_cls.id, 5]),
         'a_name':
         apply_(operator.concat, [self.a_cls.name, '-test']),
     })
     self.assertEqual(set(struct._columns), {
         self.a_cls.__table__.c.id,
         self.a_cls.__table__.c.name,
     })
     result = {
         self.a_cls.__table__.c.id: 1,
         self.a_cls.__table__.c.name: 'a1',
     }
     row = [result[col] for col in struct._columns]
     s = struct._from_row(row)
     self.assertEqual(s.a_id, 1 + 5)
     self.assertEqual(s.a_name, 'a1' + '-test')
コード例 #9
0
ファイル: tests.py プロジェクト: evo-company/sqlconstruct
    def test_pipe_operator(self):
        struct = Construct({
            'a_name_hash':
            apply_(capitalize, [self.a_cls.name]) | hash,
        })

        s1, s2 = self.session.query(struct).order_by(self.a_cls.name).all()

        self.assertEqual(s1.a_name_hash, hash('A1'))
        self.assertEqual(s2.a_name_hash, hash('A2'))
コード例 #10
0
ファイル: tests.py プロジェクト: uvNikita/sqlconstruct
    def test_apply_with_columns(self):
        f1 = self.a_cls.id
        f2 = self.b_cls.id
        c1 = self.a_cls.__table__.c.id
        c2 = self.b_cls.__table__.c.id
        fn1 = func.count(self.a_cls.id)
        fn2 = func.count(self.b_cls.id)

        add = lambda a, b: a + b

        apl1 = apply_(add, [f1], {'b': f2})
        self.assertEqual(columns_set(apl1), {c1, c2})
        self.assertEqual(proceed(apl1, {c1: 3, c2: 4}), 3 + 4)

        apl2 = apply_(add, [c1], {'b': c2})
        self.assertEqual(columns_set(apl2), {c1, c2})
        self.assertEqual(proceed(apl1, {c1: 4, c2: 5}), 4 + 5)

        apl3 = apply_(add, [fn1], {'b': fn2})
        self.assertEqual(columns_set(apl3), {fn1, fn2})
        self.assertEqual(proceed(apl3, {fn1: 5, fn2: 6}), 5 + 6)
コード例 #11
0
ファイル: tests.py プロジェクト: evo-company/sqlconstruct
    def test_apply_with_columns(self):
        f1 = self.a_cls.id
        f2 = self.b_cls.id
        c1 = self.a_cls.__table__.c.id
        c2 = self.b_cls.__table__.c.id
        fn1 = func.count(self.a_cls.id)
        fn2 = func.count(self.b_cls.id)

        add = lambda a, b: a + b

        apl1 = apply_(add, [f1], {'b': f2})
        self.assertEqual(columns_set(apl1), {c1, c2})
        self.assertEqual(proceed(apl1, {c1: 3, c2: 4}), 3 + 4)

        apl2 = apply_(add, [c1], {'b': c2})
        self.assertEqual(columns_set(apl2), {c1, c2})
        self.assertEqual(proceed(apl1, {c1: 4, c2: 5}), 4 + 5)

        apl3 = apply_(add, [fn1], {'b': fn2})
        self.assertEqual(columns_set(apl3), {fn1, fn2})
        self.assertEqual(proceed(apl3, {fn1: 5, fn2: 6}), 5 + 6)
コード例 #12
0
ファイル: tests.py プロジェクト: evo-company/sqlconstruct
    def test_apply(self):
        add = lambda a, b, c=30, d=400: a + b + c + d

        min_pos_apply = apply_(add, [1, 2])
        self.assertEqual(columns_set(min_pos_apply), set())
        self.assertEqual(proceed(min_pos_apply, {}), 1 + 2 + 30 + 400)

        min_kw_apply = apply_(add, [], {'a': 1, 'b': 2})
        self.assertEqual(columns_set(min_kw_apply), set())
        self.assertEqual(proceed(min_kw_apply, {}), 1 + 2 + 30 + 400)

        max_pos_apply = apply_(add, [1, 2, 33, 444])
        self.assertEqual(columns_set(max_pos_apply), set())
        self.assertEqual(proceed(max_pos_apply, {}), 1 + 2 + 33 + 444)

        max_kw_apply = apply_(add, [], {'a': 1, 'b': 2, 'c': 33, 'd': 444})
        self.assertEqual(columns_set(max_kw_apply), set())
        self.assertEqual(proceed(max_kw_apply, {}), 1 + 2 + 33 + 444)

        mixed_apply = apply_(add, [1, 2], {'c': 33, 'd': 444})
        self.assertEqual(columns_set(mixed_apply), set())
        self.assertEqual(proceed(mixed_apply, {}), 1 + 2 + 33 + 444)
コード例 #13
0
ファイル: tests.py プロジェクト: uvNikita/sqlconstruct
    def test_apply(self):
        add = lambda a, b, c=30, d=400: a + b + c + d

        min_pos_apply = apply_(add, [1, 2])
        self.assertEqual(columns_set(min_pos_apply), set())
        self.assertEqual(proceed(min_pos_apply, {}), 1 + 2 + 30 + 400)

        min_kw_apply = apply_(add, [], {'a': 1, 'b': 2})
        self.assertEqual(columns_set(min_kw_apply), set())
        self.assertEqual(proceed(min_kw_apply, {}), 1 + 2 + 30 + 400)

        max_pos_apply = apply_(add, [1, 2, 33, 444])
        self.assertEqual(columns_set(max_pos_apply), set())
        self.assertEqual(proceed(max_pos_apply, {}), 1 + 2 + 33 + 444)

        max_kw_apply = apply_(add, [], {'a': 1, 'b': 2, 'c': 33, 'd': 444})
        self.assertEqual(columns_set(max_kw_apply), set())
        self.assertEqual(proceed(max_kw_apply, {}), 1 + 2 + 33 + 444)

        mixed_apply = apply_(add, [1, 2], {'c': 33, 'd': 444})
        self.assertEqual(columns_set(mixed_apply), set())
        self.assertEqual(proceed(mixed_apply, {}), 1 + 2 + 33 + 444)
コード例 #14
0
ファイル: tests.py プロジェクト: evo-company/sqlconstruct
    def test_if(self):
        add = lambda a, b: a + b
        c1 = self.a_cls.__table__.c.id
        c2 = self.a_cls.__table__.c.name
        c3 = self.b_cls.__table__.c.id
        c4 = self.b_cls.__table__.c.name

        if1 = if_(True, then_=1, else_=2)
        self.assertEqual(columns_set(if1), set())
        self.assertEqual(proceed(if1, {}), 1)

        if2 = if_(False, then_=1, else_=2)
        self.assertEqual(columns_set(if2), set())
        self.assertEqual(proceed(if2, {}), 2)

        if3 = if_(c1, then_=c2, else_=c3)
        self.assertEqual(columns_set(if3), {c1, c2, c3})
        self.assertEqual(proceed(if3, {c1: 0, c2: 3, c3: 6}), 6)
        self.assertEqual(proceed(if3, {c1: 1, c2: 3, c3: 6}), 3)

        if4 = if_(c1, then_=apply_(add, [c2, c3]), else_=apply_(add, [c3, c4]))
        self.assertEqual(columns_set(if4), {c1, c2, c3, c4})
        self.assertEqual(proceed(if4, {c1: 0, c2: 2, c3: 3, c4: 4}), 3 + 4)
        self.assertEqual(proceed(if4, {c1: 1, c2: 2, c3: 3, c4: 4}), 2 + 3)
コード例 #15
0
ファイル: tests.py プロジェクト: uvNikita/sqlconstruct
    def test_if(self):
        add = lambda a, b: a + b
        c1 = self.a_cls.__table__.c.id
        c2 = self.a_cls.__table__.c.name
        c3 = self.b_cls.__table__.c.id
        c4 = self.b_cls.__table__.c.name

        if1 = if_(True, then_=1, else_=2)
        self.assertEqual(columns_set(if1), set())
        self.assertEqual(proceed(if1, {}), 1)

        if2 = if_(False, then_=1, else_=2)
        self.assertEqual(columns_set(if2), set())
        self.assertEqual(proceed(if2, {}), 2)

        if3 = if_(c1, then_=c2, else_=c3)
        self.assertEqual(columns_set(if3), {c1, c2, c3})
        self.assertEqual(proceed(if3, {c1: 0, c2: 3, c3: 6}), 6)
        self.assertEqual(proceed(if3, {c1: 1, c2: 3, c3: 6}), 3)

        if4 = if_(c1, then_=apply_(add, [c2, c3]), else_=apply_(add, [c3, c4]))
        self.assertEqual(columns_set(if4), {c1, c2, c3, c4})
        self.assertEqual(proceed(if4, {c1: 0, c2: 2, c3: 3, c4: 4}), 3 + 4)
        self.assertEqual(proceed(if4, {c1: 1, c2: 2, c3: 3, c4: 4}), 2 + 3)
コード例 #16
0
ファイル: tests.py プロジェクト: uvNikita/sqlconstruct
    def test_nested_apply(self):
        c1 = self.a_cls.__table__.c.id
        c2 = self.b_cls.__table__.c.id

        add = lambda a, b: a + b

        apl = apply_(add, [
            apply_(add, [
                apply_(add, [
                    0,
                    1,
                ]),
                apply_(add, [
                    2,
                    apply_(add, [
                        3,
                        c1,  # 4
                    ]),
                ]),
            ]),
            apply_(add, [
                apply_(add, [
                    apply_(add, [
                        c2,  # 5
                        6,
                    ]),
                    7,
                ]),
                apply_(add, [
                    8,
                    9,
                ]),
            ]),
        ])
        self.assertEqual(columns_set(apl), {c1, c2})
        self.assertEqual(proceed(apl, {c1: 4, c2: 5}), sum(range(10)))
コード例 #17
0
ファイル: tests.py プロジェクト: evo-company/sqlconstruct
    def test_one_to_many(self):
        class A(self.base_cls):
            name = Column(String)
            b_list = relationship('B')

        class B(self.base_cls):
            name = Column(String)
            a_id = Column(Integer, ForeignKey('a.id'))

        session = self.init()
        session.add_all([
            A(name='a1', b_list=[B(name='b1'),
                                 B(name='b2'),
                                 B(name='b3')]),
            A(name='a2', b_list=[B(name='b4'),
                                 B(name='b5'),
                                 B(name='b6')]),
            A(name='a3', b_list=[B(name='b7'),
                                 B(name='b8'),
                                 B(name='b9')]),
        ])
        session.commit()

        query = (ConstructQuery({
            'a_name':
            A.name,
            'b_names':
            map_(apply_(capitalize, [B.name]), A.b_list),
        }).with_session(session.registry()))
        self.assertEqual(
            tuple(dict(obj) for obj in query.all()),
            ({
                'a_name': 'a1',
                'b_names': ['B1', 'B2', 'B3']
            }, {
                'a_name': 'a2',
                'b_names': ['B4', 'B5', 'B6']
            }, {
                'a_name': 'a3',
                'b_names': ['B7', 'B8', 'B9']
            }),
        )
コード例 #18
0
ファイル: tests.py プロジェクト: evo-company/sqlconstruct
    def test_one_to_one(self):
        class A(self.base_cls):
            name = Column(String)
            b = relationship('B', uselist=False)

        class B(self.base_cls):
            name = Column(String)
            a_id = Column(Integer, ForeignKey('a.id'))

        session = self.init()
        session.add_all([
            A(name='a1', b=B(name='b1')),
            A(name='a2'),
            B(name='b2'),
            A(name='a3', b=B(name='b3')),
        ])
        session.commit()

        query = (ConstructQuery({
            'a_name':
            A.name,
            'b_name':
            get_(if_(B.id, apply_(capitalize, [B.name]), '~'), A.b),
        }).with_session(session.registry()))
        self.assertEqual(
            tuple(dict(obj) for obj in query.all()),
            ({
                'a_name': 'a1',
                'b_name': 'B1'
            }, {
                'a_name': 'a2',
                'b_name': '~'
            }, {
                'a_name': 'a3',
                'b_name': 'B3'
            }),
        )
コード例 #19
0
ファイル: tests.py プロジェクト: evo-company/sqlconstruct
    def test_defined_calls(self):
        c1 = self.a_cls.__table__.c.id
        c2 = self.a_cls.__table__.c.name
        c3 = self.b_cls.__table__.c.id
        c4 = self.b_cls.__table__.c.name

        self.assertEqual(
            defined_func(self.a_cls(id=1, name='foo'),
                         self.b_cls(id=2, name='bar'),
                         extra_id=3,
                         extra_name='baz'),
            (1, 2, 3, 'foo', 'bar', 'baz'),
        )

        self.assertEqual(
            defined_func(self.a_cls(id=1, name='foo'),
                         None,
                         extra_id=3,
                         extra_name='baz'),
            (1, None, 3, 'foo', None, 'baz'),
        )

        self.assertEqual(
            defined_func(None,
                         self.b_cls(id=2, name='bar'),
                         extra_id=3,
                         extra_name='baz'),
            (None, 2, 3, None, 'bar', 'baz'),
        )

        apl1 = defined_func.defn(self.a_cls,
                                 self.b_cls,
                                 extra_id=3,
                                 extra_name='baz')
        self.assertTrue(isinstance(apl1, apply_), type(apl1))
        self.assertEqual(columns_set(apl1), {c1, c2, c3, c4})
        self.assertEqual(
            proceed(apl1, {
                c1: 1,
                c2: 'foo',
                c3: 2,
                c4: 'bar'
            }),
            (1, 2, 3, 'foo', 'bar', 'baz'),
        )

        apl2 = defined_func.defn(self.a_cls,
                                 self.b_cls,
                                 extra_id=c1,
                                 extra_name=c2)
        self.assertTrue(isinstance(apl2, apply_), type(apl2))
        self.assertEqual(columns_set(apl2), {c1, c2, c3, c4})
        self.assertEqual(
            proceed(apl2, {
                c1: 1,
                c2: 'foo',
                c3: 2,
                c4: 'bar'
            }),
            (1, 2, 1, 'foo', 'bar', 'foo'),
        )

        apl3 = defined_func.defn(self.a_cls,
                                 self.b_cls,
                                 extra_id=apply_(operator.add, [c1, c3]),
                                 extra_name=apply_(operator.concat, [c2, c4]))
        self.assertTrue(isinstance(apl3, apply_), type(apl3))
        self.assertEqual(columns_set(apl3), {c1, c2, c3, c4})
        self.assertEqual(
            proceed(apl3, {
                c1: 1,
                c2: 'foo',
                c3: 2,
                c4: 'bar'
            }),
            (1, 2, (1 + 2), 'foo', 'bar', ('foo' + 'bar')),
        )

        self.assertEqual(
            defined_func.func(1, 'foo', 2, 'bar', 3, 'baz'),
            (1, 2, 3, 'foo', 'bar', 'baz'),
        )
コード例 #20
0
ファイル: tests.py プロジェクト: uvNikita/sqlconstruct
    def test_many_to_many(self):
        ab_table = Table(
            'a_b',
            self.base_cls.metadata,
            Column('a_id', Integer, ForeignKey('a.id')),
            Column('b_id', Integer, ForeignKey('b.id'))
        )

        class A(self.base_cls):
            name = Column(String)
            b_list = relationship('B', secondary=ab_table)

        class B(self.base_cls):
            name = Column(String)
            a_list = relationship('A', secondary=ab_table)

        session = self.init()
        a1, a2, a3, a4 = A(name='a1'), A(name='a2'), A(name='a3'), A(name='a4')
        b1, b2, b3, b4 = B(name='b1'), B(name='b2'), B(name='b3'), B(name='b4')
        a1.b_list = [b2, b3, b4]
        a2.b_list = [b1, b3, b4]
        a3.b_list = [b1, b2, b4]
        a4.b_list = [b1, b2, b3]
        session.add_all([a1, a2, a3, a4])
        session.commit()

        q1 = (
            ConstructQuery({
                'a_name': A.name,
                'b_names': map_(apply_(capitalize, [B.name]), A.b_list),
            })
            .with_session(session.registry())
            .order_by(A.name)
        )
        self.assertEqual(
            tuple((obj.a_name, set(obj.b_names)) for obj in q1.all()),
            (
                ('a1', {'B2', 'B3', 'B4'}),
                ('a2', {'B1', 'B3', 'B4'}),
                ('a3', {'B1', 'B2', 'B4'}),
                ('a4', {'B1', 'B2', 'B3'}),
            )
        )

        q2 = (
            ConstructQuery({
                'b_name': B.name,
                'a_names': map_(apply_(capitalize, [A.name]), B.a_list),
            })
            .with_session(session.registry())
            .order_by(B.name)
        )
        self.assertEqual(
            tuple((obj.b_name, set(obj.a_names)) for obj in q2.all()),
            (
                ('b1', {'A2', 'A3', 'A4'}),
                ('b2', {'A1', 'A3', 'A4'}),
                ('b3', {'A1', 'A2', 'A4'}),
                ('b4', {'A1', 'A2', 'A3'}),
            ),
        )