Пример #1
0
    def test_nested_get_with_null_value_in_outer_expr(self):
        class A(self.base_cls):
            name = Column(String)
            b_id = Column('b_id', Integer, ForeignKey('b.id'))
            b = relationship('B', backref='a_list')

        class B(self.base_cls):
            name = Column(String)
            c_id = Column('c_id', Integer, ForeignKey('c.id'))
            c = relationship('C', backref='b_list')

        class C(self.base_cls):
            name = Column(String)

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

        res = tuple(dict(obj) for obj in ConstructQuery({
            'a_name': A.name,
            'b_name': get_(B.name, A.b),
            'c_name': get_(get_(C.name, B.c), A.b),
        }).with_session(session.registry()).order_by(A.name).all())
        self.assertEqual(res, (
            {'a_name': 'a1', 'b_name': 'b1', 'c_name': 'c1'},
            {'a_name': 'a2', 'b_name': 'b2', 'c_name': None},
            {'a_name': 'a3', 'b_name': None, 'c_name': None},
        ))
Пример #2
0
    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'}),
        )
Пример #3
0
    def test_with_custom_queries(self):

        class A(self.base_cls):
            name = Column(String)

        class B(self.base_cls):
            name = Column(String)

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

        sq1 = CollectionSubQuery(B).order_by(B.name.desc())
        q1 = (
            ConstructQuery({'a_name': A.name, 'b_list': map_(B.name, sq1)},
                           session)
            .order_by(A.name)
        )
        self.assertEqual({(obj.a_name, tuple(obj.b_list)) for obj in q1.all()},
                         {('a1', ('b3', 'b2', 'b1')),
                          ('a2', ('b3', 'b2', 'b1')),
                          ('a3', ('b3', 'b2', 'b1'))})

        sq2 = ObjectSubQuery(B).order_by(B.name.desc())
        q2 = (
            ConstructQuery({'a_name': A.name, 'b_name': get_(B.name, sq2)},
                           session)
            .order_by(A.name)
        )
        self.assertEqual({(obj.a_name, obj.b_name) for obj in q2.all()},
                         {('a1', 'b3'), ('a2', 'b3'), ('a3', 'b3')})
Пример #4
0
    def test_non_empty_in_op_in_relative_subqueries(self):
        in_op = ColumnOperators.in_

        class EmptyInOpError(Exception):
            pass

        def wrapper(self, values):
            if not values:
                raise EmptyInOpError
            return in_op(self, values)

        patcher = patch.object(ColumnOperators, 'in_', wrapper)

        class A(self.base_cls):
            value = Column(String)

        class B(self.base_cls):
            value = Column(String)

        session = self.init()
        session.add_all([A(), A(), A()])
        session.commit()

        obj_sq = RelativeObjectSubQuery(A.value, B.value)
        obj_query = ConstructQuery({
            'a_id': A.id,
            'b_id': get_(B.id, obj_sq)
        }, session)
        with patcher:
            obj_query.all()

        list_sq = RelativeCollectionSubQuery(A.value, B.value)
        list_query = ConstructQuery({
            'a_id': A.id,
            'b_id': map_(B.id, list_sq)
        }, session)
        with patcher:
            list_query.all()
Пример #5
0
    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'
            }),
        )
Пример #6
0
    def test_bound_to_query_expressions(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')]),
            A(name='a2', b_list=[B(name='b4'), B(name='b5')]),
            A(name='a3', b_list=[B(name='b7'),
                                 B(name='b8'),
                                 B(name='b9')]),
        ])
        session.commit()

        sq = (RelativeObjectSubQuery.from_relation(A.b_list).group_by(B.a_id))
        query = (ConstructQuery({
            'a_name': A.name,
            'b_count': get_(bind(func.count(), sq), sq),
        }).order_by(A.name.asc()).with_session(session.registry()))
        self.assertEqual(
            [dict(obj) for obj in query.all()],
            [{
                'a_name': 'a1',
                'b_count': 1
            }, {
                'a_name': 'a2',
                'b_count': 2
            }, {
                'a_name': 'a3',
                'b_count': 3
            }],
        )
Пример #7
0
    def test_with_custom_queries(self):
        class A(self.base_cls):
            name = Column(String)

        class B(self.base_cls):
            name = Column(String)

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

        sq1 = CollectionSubQuery(B).order_by(B.name.desc())
        q1 = (ConstructQuery({
            'a_name': A.name,
            'b_list': map_(B.name, sq1)
        }, session).order_by(A.name))
        self.assertEqual({(obj.a_name, tuple(obj.b_list))
                          for obj in q1.all()}, {('a1', ('b3', 'b2', 'b1')),
                                                 ('a2', ('b3', 'b2', 'b1')),
                                                 ('a3', ('b3', 'b2', 'b1'))})

        sq2 = ObjectSubQuery(B).order_by(B.name.desc())
        q2 = (ConstructQuery({
            'a_name': A.name,
            'b_name': get_(B.name, sq2)
        }, session).order_by(A.name))
        self.assertEqual({(obj.a_name, obj.b_name)
                          for obj in q2.all()}, {('a1', 'b3'), ('a2', 'b3'),
                                                 ('a3', 'b3')})
Пример #8
0
    def test_non_empty_in_op_in_relative_subqueries(self):
        in_op = ColumnOperators.in_

        class EmptyInOpError(Exception):
            pass

        def wrapper(self, values):
            if not values:
                raise EmptyInOpError
            return in_op(self, values)

        patcher = patch.object(ColumnOperators, 'in_', wrapper)

        class A(self.base_cls):
            value = Column(String)

        class B(self.base_cls):
            value = Column(String)

        session = self.init()
        session.add_all([A(), A(), A()])
        session.commit()

        obj_sq = RelativeObjectSubQuery(A.value, B.value)
        obj_query = ConstructQuery({'a_id': A.id,
                                    'b_id': get_(B.id, obj_sq)},
                                   session)
        with patcher:
            obj_query.all()

        list_sq = RelativeCollectionSubQuery(A.value, B.value)
        list_query = ConstructQuery({'a_id': A.id,
                                     'b_id': map_(B.id, list_sq)},
                                    session)
        with patcher:
            list_query.all()
Пример #9
0
    def test_bound_to_query_expressions(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')]),
            A(name='a2', b_list=[B(name='b4'), B(name='b5')]),
            A(name='a3', b_list=[B(name='b7'), B(name='b8'), B(name='b9')]),
        ])
        session.commit()

        sq = (
            RelativeObjectSubQuery.from_relation(A.b_list)
            .group_by(B.a_id)
        )
        query = (
            ConstructQuery({
                'a_name': A.name,
                'b_count': get_(bind(func.count(), sq), sq),
            })
            .order_by(A.name.asc())
            .with_session(session.registry())
        )
        self.assertEqual(
            [dict(obj) for obj in query.all()],
            [{'a_name': 'a1', 'b_count': 1},
             {'a_name': 'a2', 'b_count': 2},
             {'a_name': 'a3', 'b_count': 3}],
        )
Пример #10
0
    def test_nested(self):
        """
        A <- B -> C -> D <- E
        """
        class A(self.base_cls):
            name = Column(String)

        class B(self.base_cls):
            name = Column(String)
            a_id = Column('a_id', Integer, ForeignKey('a.id'))
            a = relationship('A', backref='b_list')
            c_id = Column('c_id', Integer, ForeignKey('c.id'))
            c = relationship('C', backref='b_list')

        class C(self.base_cls):
            name = Column(String)
            d_id = Column('d_id', Integer, ForeignKey('d.id'))
            d = relationship('D', backref='c_list')

        class D(self.base_cls):
            name = Column(String)

        class E(self.base_cls):
            name = Column(String)
            d_id = Column('d_id', Integer, ForeignKey('d.id'))
            d = relationship('D', backref='e_list')

        session = self.init()
        a1, a2, a3 = A(name='a1'), A(name='a2'), A(name='a3')
        d1 = D(name='d1',
               c_list=[
                   C(name='c1',
                     b_list=[
                         B(name='b1'),
                         B(name='b2', a=a2),
                         B(name='b3', a=a3)
                     ]),
                   C(name='c2',
                     b_list=[
                         B(name='b4', a=a1),
                         B(name='b5'),
                         B(name='b6', a=a3)
                     ]),
                   C(name='c3',
                     b_list=[
                         B(name='b7', a=a1),
                         B(name='b8', a=a2),
                         B(name='b9')
                     ])
               ],
               e_list=[E(name='e1'), E(name='e2'),
                       E(name='e3')])
        session.add_all([a1, a2, a3, d1])
        session.commit()

        # A <- B -> C
        r1 = tuple(
            dict(obj) for obj in ConstructQuery(
                {
                    'a_name': A.name,
                    'b_names': map_(B.name, A.b_list),
                    'c_names': map_(get_(C.name, B.c), A.b_list)
                }).with_session(session.registry()).order_by(A.name).all())
        self.assertEqual(r1, (
            {
                'a_name': 'a1',
                'b_names': ['b4', 'b7'],
                'c_names': ['c2', 'c3']
            },
            {
                'a_name': 'a2',
                'b_names': ['b2', 'b8'],
                'c_names': ['c1', 'c3']
            },
            {
                'a_name': 'a3',
                'b_names': ['b3', 'b6'],
                'c_names': ['c1', 'c2']
            },
        ))

        # B -> C -> D
        r2 = tuple(
            dict(obj)
            for obj in ConstructQuery({
                'b_name': B.name,
                'c_name': get_(C.name, B.c),
                'd_name': get_(get_(D.name, C.d), B.c),
            }).with_session(session.registry()).order_by(B.name).all())
        self.assertEqual(r2, (
            {
                'b_name': 'b1',
                'c_name': 'c1',
                'd_name': 'd1'
            },
            {
                'b_name': 'b2',
                'c_name': 'c1',
                'd_name': 'd1'
            },
            {
                'b_name': 'b3',
                'c_name': 'c1',
                'd_name': 'd1'
            },
            {
                'b_name': 'b4',
                'c_name': 'c2',
                'd_name': 'd1'
            },
            {
                'b_name': 'b5',
                'c_name': 'c2',
                'd_name': 'd1'
            },
            {
                'b_name': 'b6',
                'c_name': 'c2',
                'd_name': 'd1'
            },
            {
                'b_name': 'b7',
                'c_name': 'c3',
                'd_name': 'd1'
            },
            {
                'b_name': 'b8',
                'c_name': 'c3',
                'd_name': 'd1'
            },
            {
                'b_name': 'b9',
                'c_name': 'c3',
                'd_name': 'd1'
            },
        ))

        # C -> D <- E
        r3 = tuple(
            dict(obj) for obj in ConstructQuery(
                {
                    'c_name': C.name,
                    'd_name': get_(D.name, C.d),
                    'e_names': get_(map_(E.name, D.e_list), C.d),
                }).with_session(session.registry()).order_by(C.name).all())
        self.assertEqual(r3, (
            {
                'c_name': 'c1',
                'd_name': 'd1',
                'e_names': ['e1', 'e2', 'e3']
            },
            {
                'c_name': 'c2',
                'd_name': 'd1',
                'e_names': ['e1', 'e2', 'e3']
            },
            {
                'c_name': 'c3',
                'd_name': 'd1',
                'e_names': ['e1', 'e2', 'e3']
            },
        ))

        # D <- C <- B
        r4 = dict(
            ConstructQuery({
                'd_name': D.name,
                'c_names': map_(C.name, D.c_list),
                'b_names': map_(map_(B.name, C.b_list), D.c_list),
            }).with_session(session.registry()).order_by(D.name).one())
        self.assertEqual(r4['d_name'], 'd1')
        self.assertEqual(set(r4['c_names']), {'c1', 'c2', 'c3'})
        self.assertEqual(
            set(map(frozenset, r4['b_names'])), {
                frozenset({'b1', 'b2', 'b3'}),
                frozenset({'b4', 'b5', 'b6'}),
                frozenset({'b7', 'b8', 'b9'}),
            })
Пример #11
0
    def test_nested(self):
        """
        A <- B -> C -> D <- E
        """
        class A(self.base_cls):
            name = Column(String)

        class B(self.base_cls):
            name = Column(String)
            a_id = Column('a_id', Integer, ForeignKey('a.id'))
            a = relationship('A', backref='b_list')
            c_id = Column('c_id', Integer, ForeignKey('c.id'))
            c = relationship('C', backref='b_list')

        class C(self.base_cls):
            name = Column(String)
            d_id = Column('d_id', Integer, ForeignKey('d.id'))
            d = relationship('D', backref='c_list')

        class D(self.base_cls):
            name = Column(String)

        class E(self.base_cls):
            name = Column(String)
            d_id = Column('d_id', Integer, ForeignKey('d.id'))
            d = relationship('D', backref='e_list')

        session = self.init()
        a1, a2, a3 = A(name='a1'), A(name='a2'), A(name='a3')
        d1 = D(name='d1',
               c_list=[C(name='c1',
                         b_list=[B(name='b1'),
                                 B(name='b2', a=a2),
                                 B(name='b3', a=a3)]),
                       C(name='c2',
                         b_list=[B(name='b4', a=a1),
                                 B(name='b5'),
                                 B(name='b6', a=a3)]),
                       C(name='c3',
                         b_list=[B(name='b7', a=a1),
                                 B(name='b8', a=a2),
                                 B(name='b9')])],
               e_list=[E(name='e1'), E(name='e2'), E(name='e3')])
        session.add_all([a1, a2, a3, d1])
        session.commit()

        # A <- B -> C
        r1 = tuple(dict(obj) for obj in ConstructQuery({
            'a_name': A.name,
            'b_names': map_(B.name, A.b_list),
            'c_names': map_(get_(C.name, B.c), A.b_list)
        }).with_session(session.registry()).order_by(A.name).all())
        self.assertEqual(r1, (
            {'a_name': 'a1', 'b_names': ['b4', 'b7'], 'c_names': ['c2', 'c3']},
            {'a_name': 'a2', 'b_names': ['b2', 'b8'], 'c_names': ['c1', 'c3']},
            {'a_name': 'a3', 'b_names': ['b3', 'b6'], 'c_names': ['c1', 'c2']},
        ))

        # B -> C -> D
        r2 = tuple(dict(obj) for obj in ConstructQuery({
            'b_name': B.name,
            'c_name': get_(C.name, B.c),
            'd_name': get_(get_(D.name, C.d), B.c),
        }).with_session(session.registry()).order_by(B.name).all())
        self.assertEqual(r2, (
            {'b_name': 'b1', 'c_name': 'c1', 'd_name': 'd1'},
            {'b_name': 'b2', 'c_name': 'c1', 'd_name': 'd1'},
            {'b_name': 'b3', 'c_name': 'c1', 'd_name': 'd1'},
            {'b_name': 'b4', 'c_name': 'c2', 'd_name': 'd1'},
            {'b_name': 'b5', 'c_name': 'c2', 'd_name': 'd1'},
            {'b_name': 'b6', 'c_name': 'c2', 'd_name': 'd1'},
            {'b_name': 'b7', 'c_name': 'c3', 'd_name': 'd1'},
            {'b_name': 'b8', 'c_name': 'c3', 'd_name': 'd1'},
            {'b_name': 'b9', 'c_name': 'c3', 'd_name': 'd1'},
        ))

        # C -> D <- E
        r3 = tuple(dict(obj) for obj in ConstructQuery({
            'c_name': C.name,
            'd_name': get_(D.name, C.d),
            'e_names': get_(map_(E.name, D.e_list), C.d),
        }).with_session(session.registry()).order_by(C.name).all())
        self.assertEqual(r3, (
            {'c_name': 'c1', 'd_name': 'd1', 'e_names': ['e1', 'e2', 'e3']},
            {'c_name': 'c2', 'd_name': 'd1', 'e_names': ['e1', 'e2', 'e3']},
            {'c_name': 'c3', 'd_name': 'd1', 'e_names': ['e1', 'e2', 'e3']},
        ))

        # D <- C <- B
        r4 = dict(ConstructQuery({
            'd_name': D.name,
            'c_names': map_(C.name, D.c_list),
            'b_names': map_(map_(B.name, C.b_list), D.c_list),
        }).with_session(session.registry()).order_by(D.name).one())
        self.assertEqual(r4['d_name'], 'd1')
        self.assertEqual(set(r4['c_names']), {'c1', 'c2', 'c3'})
        self.assertEqual(set(map(frozenset, r4['b_names'])), {
            frozenset({'b1', 'b2', 'b3'}),
            frozenset({'b4', 'b5', 'b6'}),
            frozenset({'b7', 'b8', 'b9'}),
        })