~ubuntu-branches/debian/jessie/sqlalchemy/jessie

« back to all changes in this revision

Viewing changes to test/orm/inheritance/test_polymorphic_rel.py

  • Committer: Package Import Robot
  • Author(s): Piotr Ożarowski, Jakub Wilk, Piotr Ożarowski
  • Date: 2013-07-06 20:53:52 UTC
  • mfrom: (1.4.23) (16.1.17 experimental)
  • Revision ID: package-import@ubuntu.com-20130706205352-ryppl1eto3illd79
Tags: 0.8.2-1
[ Jakub Wilk ]
* Use canonical URIs for Vcs-* fields.

[ Piotr Ożarowski ]
* New upstream release
* Upload to unstable
* Build depend on python3-all instead of -dev, extensions are not built for
  Python 3.X 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
from sqlalchemy import Integer, String, ForeignKey, func, desc, and_, or_
2
 
from sqlalchemy.orm import interfaces, relationship, mapper, \
3
 
    clear_mappers, create_session, joinedload, joinedload_all, \
4
 
    subqueryload, subqueryload_all, polymorphic_union, aliased,\
 
1
from sqlalchemy import func, desc
 
2
from sqlalchemy.orm import interfaces, create_session, joinedload, joinedload_all, \
 
3
    subqueryload, subqueryload_all, aliased,\
5
4
    class_mapper
6
5
from sqlalchemy import exc as sa_exc
7
 
from sqlalchemy.engine import default
8
6
 
9
 
from test.lib import AssertsCompiledSQL, fixtures, testing
10
 
from test.lib.schema import Table, Column
11
 
from test.lib.testing import assert_raises, eq_
 
7
from sqlalchemy import testing
 
8
from sqlalchemy.testing import assert_raises, eq_
12
9
 
13
10
from _poly_fixtures import Company, Person, Engineer, Manager, Boss, \
14
 
    Machine, Paperwork, _PolymorphicFixtureBase, _Polymorphic,\
 
11
    Machine, Paperwork, _Polymorphic,\
15
12
    _PolymorphicPolymorphic, _PolymorphicUnions, _PolymorphicJoins,\
16
13
    _PolymorphicAliasedJoins
17
14
 
323
320
                .filter(any_).all(),
324
321
            [])
325
322
 
326
 
    def test_polymorphic_any_four(self):
327
 
        sess = create_session()
328
 
        any_ = Company.employees.of_type(Engineer).any(
329
 
            Engineer.primary_language == 'cobol')
330
 
        eq_(sess.query(Company).filter(any_).one(), c2)
331
 
 
332
 
    def test_polymorphic_any_five(self):
333
 
        sess = create_session()
334
 
        calias = aliased(Company)
335
 
        any_ = calias.employees.of_type(Engineer).any(
336
 
            Engineer.primary_language == 'cobol')
337
 
        eq_(sess.query(calias).filter(any_).one(), c2)
338
 
 
339
 
    def test_polymorphic_any_six(self):
340
 
        sess = create_session()
341
 
        any_ = Company.employees.of_type(Boss).any(
342
 
            Boss.golf_swing == 'fore')
343
 
        eq_(sess.query(Company).filter(any_).one(), c1)
344
 
 
345
 
    def test_polymorphic_any_seven(self):
346
 
        sess = create_session()
347
 
        any_ = Company.employees.of_type(Boss).any(
348
 
            Manager.manager_name == 'pointy')
349
 
        eq_(sess.query(Company).filter(any_).one(), c1)
350
 
 
351
323
    def test_polymorphic_any_eight(self):
352
324
        sess = create_session()
353
325
        any_ = Engineer.machines.any(
360
332
            Paperwork.description == "review #2")
361
333
        eq_(sess.query(Person).filter(any_).all(), [m1])
362
334
 
363
 
    def test_polymorphic_any_ten(self):
364
 
        sess = create_session()
365
 
        any_ = Company.employees.of_type(Engineer).any(
366
 
            and_(Engineer.primary_language == 'cobol'))
367
 
        eq_(sess.query(Company).filter(any_).one(), c2)
368
335
 
369
336
    def test_join_from_columns_or_subclass_one(self):
370
337
        sess = create_session()
529
496
                .all(),
530
497
            expected)
531
498
 
532
 
    def test_polymorphic_option(self):
533
 
        """
534
 
        Test that polymorphic loading sets state.load_path with its
535
 
        actual mapper on a subclass, and not the superclass mapper.
536
 
        """
537
 
 
538
 
        paths = []
539
 
        class MyOption(interfaces.MapperOption):
540
 
            propagate_to_loaders = True
541
 
            def process_query_conditionally(self, query):
542
 
                paths.append(query._current_path)
543
 
 
 
499
 
 
500
    def test_subclass_option_pathing(self):
 
501
        from sqlalchemy.orm import defer
544
502
        sess = create_session()
545
 
        names = ['dilbert', 'pointy haired boss']
546
 
        dilbert, boss = (
547
 
            sess.query(Person)
548
 
                .options(MyOption())
549
 
                .filter(Person.name.in_(names))
550
 
                .order_by(Person.name).all())
551
 
 
552
 
        dilbert.machines
553
 
        boss.paperwork
554
 
 
555
 
        eq_(paths,
556
 
            [(class_mapper(Engineer), 'machines'),
557
 
            (class_mapper(Boss), 'paperwork')])
 
503
        dilbert = sess.query(Person).\
 
504
                options(defer(Engineer.machines, Machine.name)).\
 
505
                filter(Person.name == 'dilbert').first()
 
506
        m = dilbert.machines[0]
 
507
        assert 'name' not in m.__dict__
 
508
        eq_(m.name, 'IBM ThinkPad')
558
509
 
559
510
    def test_expire(self):
560
511
        """
639
590
            self._emps_wo_relationships_fixture())
640
591
 
641
592
 
642
 
    def test_relationship_to_polymorphic(self):
643
 
        expected = [
644
 
            Company(
645
 
                name="MegaCorp, Inc.",
646
 
                employees=[
647
 
                    Engineer(
648
 
                        name="dilbert",
649
 
                        engineer_name="dilbert",
650
 
                        primary_language="java",
651
 
                        status="regular engineer",
652
 
                        machines=[
653
 
                            Machine(name="IBM ThinkPad"),
654
 
                            Machine(name="IPhone")]),
655
 
                    Engineer(
656
 
                        name="wally",
657
 
                        engineer_name="wally",
658
 
                        primary_language="c++",
659
 
                        status="regular engineer"),
660
 
                    Boss(
661
 
                        name="pointy haired boss",
662
 
                        golf_swing="fore",
663
 
                        manager_name="pointy",
664
 
                        status="da boss"),
665
 
                    Manager(
666
 
                        name="dogbert",
667
 
                        manager_name="dogbert",
668
 
                        status="regular manager"),
669
 
                ]),
670
 
            Company(
671
 
                name="Elbonia, Inc.",
672
 
                employees=[
673
 
                    Engineer(
674
 
                        name="vlad",
675
 
                        engineer_name="vlad",
676
 
                        primary_language="cobol",
677
 
                        status="elbonian engineer")
678
 
                ])
679
 
        ]
680
 
 
 
593
    def test_relationship_to_polymorphic_one(self):
 
594
        expected = self._company_with_emps_machines_fixture()
681
595
        sess = create_session()
682
596
        def go():
683
597
            # test load Companies with lazy load to 'employees'
684
598
            eq_(sess.query(Company).all(), expected)
685
 
        count = {'':9, 'Polymorphic':4}.get(self.select_type, 5)
 
599
        count = {'':10, 'Polymorphic':5}.get(self.select_type, 6)
686
600
        self.assert_sql_count(testing.db, go, count)
687
601
 
 
602
    def test_relationship_to_polymorphic_two(self):
 
603
        expected = self._company_with_emps_machines_fixture()
688
604
        sess = create_session()
689
605
        def go():
690
 
            # currently, it doesn't matter if we say Company.employees,
691
 
            # or Company.employees.of_type(Engineer).  joinedloader
692
 
            # doesn't pick up on the "of_type()" as of yet.
 
606
            # with #2438, of_type() is recognized.  This
 
607
            # overrides the with_polymorphic of the mapper
 
608
            # and we get a consistent 3 queries now.
693
609
            eq_(sess.query(Company)
694
610
                    .options(joinedload_all(
695
611
                        Company.employees.of_type(Engineer),
696
612
                        Engineer.machines))
697
613
                    .all(),
698
614
                expected)
699
 
        # in the case of select_type='', the joinedload
700
 
        # doesn't take in this case; it joinedloads company->people,
701
 
        # then a load for each of 5 rows, then lazyload of "machines"
702
 
        count = {'':7, 'Polymorphic':1}.get(self.select_type, 2)
 
615
 
 
616
        # in the old case, we would get this
 
617
        #count = {'':7, 'Polymorphic':1}.get(self.select_type, 2)
 
618
 
 
619
        # query one is company->Person/Engineer->Machines
 
620
        # query two is managers + boss for row #3
 
621
        # query three is managers for row #4
 
622
        count = 3
703
623
        self.assert_sql_count(testing.db, go, count)
704
624
 
 
625
    def test_relationship_to_polymorphic_three(self):
 
626
        expected = self._company_with_emps_machines_fixture()
 
627
        sess = create_session()
 
628
 
705
629
        sess = create_session()
706
630
        def go():
707
631
            eq_(sess.query(Company)
710
634
                        Engineer.machines))
711
635
                    .all(),
712
636
                expected)
713
 
        count = {
714
 
            '':8,
715
 
            'Joins':4,
716
 
            'Unions':4,
717
 
            'Polymorphic':3,
718
 
            'AliasedJoins':4}[self.select_type]
 
637
 
 
638
        # the old case where subqueryload_all
 
639
        # didn't work with of_tyoe
 
640
        #count = { '':8, 'Joins':4, 'Unions':4, 'Polymorphic':3,
 
641
        #    'AliasedJoins':4}[self.select_type]
 
642
 
 
643
        # query one is company->Person/Engineer->Machines
 
644
        # query two is Person/Engineer subq
 
645
        # query three is Machines subq
 
646
        # (however this test can't tell if the Q was a
 
647
        # lazyload or subqload ...)
 
648
        # query four is managers + boss for row #3
 
649
        # query five is managers for row #4
 
650
        count = 5
719
651
        self.assert_sql_count(testing.db, go, count)
720
652
 
 
653
 
721
654
    def test_joinedload_on_subclass(self):
722
655
        sess = create_session()
723
656
        expected = [
869
802
                .filter(Machine.name.ilike("%ibm%")).all(),
870
803
            [e1, e3])
871
804
 
872
 
    def test_join_to_subclass_eightteen(self):
873
 
        sess = create_session()
874
 
        # here's the new way
875
 
        eq_(sess.query(Company)
876
 
                .join(Company.employees.of_type(Engineer))
877
 
                .filter(Engineer.primary_language == 'java').all(),
878
 
            [c1])
879
 
 
880
 
    def test_join_to_subclass_nineteen(self):
881
 
        sess = create_session()
882
 
        eq_(sess.query(Company)
883
 
                .join(Company.employees.of_type(Engineer), 'machines')
884
 
                .filter(Machine.name.ilike("%thinkpad%")).all(),
885
 
            [c1])
886
 
 
887
 
    def test_join_to_subclass_count(self):
888
 
        sess = create_session()
889
 
 
890
 
        eq_(sess.query(Company, Engineer)
891
 
                .join(Company.employees.of_type(Engineer))
892
 
                .filter(Engineer.primary_language == 'java').count(),
893
 
            1)
894
 
 
895
 
        # test [ticket:2093]
896
 
        eq_(sess.query(Company.company_id, Engineer)
897
 
                .join(Company.employees.of_type(Engineer))
898
 
                .filter(Engineer.primary_language == 'java').count(),
899
 
            1)
900
 
 
901
 
        eq_(sess.query(Company)
902
 
                .join(Company.employees.of_type(Engineer))
903
 
                .filter(Engineer.primary_language == 'java').count(),
904
 
            1)
905
 
 
906
805
    def test_join_through_polymorphic_nonaliased_one(self):
907
806
        sess = create_session()
908
807
        eq_(sess.query(Company)
1034
933
                .filter(palias.name.in_(['dilbert', 'wally'])).all(),
1035
934
            [e1, e2])
1036
935
 
1037
 
    def test_self_referential(self):
 
936
    def test_self_referential_one(self):
1038
937
        sess = create_session()
1039
938
        palias = aliased(Person)
1040
939
        expected = [(m1, e1), (m1, e2), (m1, b1)]
1046
945
                .order_by(Person.person_id, palias.person_id).all(),
1047
946
            expected)
1048
947
 
 
948
    def test_self_referential_two(self):
 
949
        sess = create_session()
 
950
        palias = aliased(Person)
 
951
        expected = [(m1, e1), (m1, e2), (m1, b1)]
 
952
 
1049
953
        eq_(sess.query(Person, palias)
1050
954
                .filter(Person.company_id == palias.company_id)
1051
955
                .filter(Person.name == 'dogbert')
1364
1268
class PolymorphicAliasedJoinsTest(_PolymorphicTestBase, _PolymorphicAliasedJoins):
1365
1269
    pass
1366
1270
 
1367
 
 
1368
1271
class PolymorphicJoinsTest(_PolymorphicTestBase, _PolymorphicJoins):
1369
1272
    pass