summaryrefslogtreecommitdiff
path: root/test/orm/inheritance/query.py
blob: bace4e6cf14c80baa96ad3d330bff7f16f79bc6a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
"""tests the Query object's ability to work with polymorphic selectables
and inheriting mappers."""

# TODO: under construction !

import testenv; testenv.configure_for_tests()
import sets
from sqlalchemy import *
from sqlalchemy.orm import *
from testlib import *
from testlib import fixtures

class Company(fixtures.Base):
    pass

class Person(fixtures.Base):
    pass
class Engineer(Person):
    pass
class Manager(Person):
    pass
class Boss(Manager):
    pass

class Paperwork(fixtures.Base):
    pass

class PolymorphicQueryTest(ORMTest):
    keep_data = True
    keep_mappers = True

    def define_tables(self, metadata):
        global companies, people, engineers, managers, boss, paperwork

        companies = Table('companies', metadata,
           Column('company_id', Integer, Sequence('company_id_seq', optional=True), primary_key=True),
           Column('name', String(50)))

        people = Table('people', metadata,
           Column('person_id', Integer, Sequence('person_id_seq', optional=True), primary_key=True),
           Column('company_id', Integer, ForeignKey('companies.company_id')),
           Column('name', String(50)),
           Column('type', String(30)))

        engineers = Table('engineers', metadata,
           Column('person_id', Integer, ForeignKey('people.person_id'), primary_key=True),
           Column('status', String(30)),
           Column('engineer_name', String(50)),
           Column('primary_language', String(50)),
          )

        managers = Table('managers', metadata,
           Column('person_id', Integer, ForeignKey('people.person_id'), primary_key=True),
           Column('status', String(30)),
           Column('manager_name', String(50))
           )

        boss = Table('boss', metadata,
            Column('boss_id', Integer, ForeignKey('managers.person_id'), primary_key=True),
            Column('golf_swing', String(30)),
            )

        paperwork = Table('paperwork', metadata,
            Column('paperwork_id', Integer, primary_key=True),
            Column('description', String(50)),
            Column('person_id', Integer, ForeignKey('people.person_id')))

        # create the most awkward polymorphic selects possible;
        # the union does not include the "people" table by itself nor does it have
        # "people.person_id" directly in it, and it also does not include at all
        # the "boss" table
        person_join = polymorphic_union(
            {
                'engineer':people.join(engineers),
                'manager':people.join(managers),
            }, None, 'pjoin')

        # separate join for second-level inherit
        manager_join = people.join(managers).outerjoin(boss)

        mapper(Company, companies, properties={
            'employees':relation(Person)
        })
        mapper(Person, people, select_table=person_join, polymorphic_on=people.c.type, polymorphic_identity='person', order_by=person_join.c.person_id,
            properties={
                'paperwork':relation(Paperwork)
            })
        mapper(Engineer, engineers, inherits=Person, polymorphic_identity='engineer')
        mapper(Manager, managers, select_table=manager_join, inherits=Person, polymorphic_identity='manager')
        mapper(Boss, boss, inherits=Manager, polymorphic_identity='boss')
        mapper(Paperwork, paperwork)

    def insert_data(self):
        c1 = Company(name="MegaCorp, Inc.")
        c2 = Company(name="Elbonia, Inc.")
        e1 = Engineer(name="dilbert", engineer_name="dilbert", primary_language="java", status="regular engineer", paperwork=[
            Paperwork(description="tps report #1"),
            Paperwork(description="tps report #2")
        ])
        e2 = Engineer(name="wally", engineer_name="wally", primary_language="c++", status="regular engineer", paperwork=[
            Paperwork(description="tps report #3"),
            Paperwork(description="tps report #4")
        ])
        b1 = Boss(name="pointy haired boss", golf_swing="fore", manager_name="pointy", status="da boss", paperwork=[
            Paperwork(description="review #1"),
        ])
        m1 = Manager(name="dogbert", manager_name="dogbert", status="regular manager", paperwork=[
            Paperwork(description="review #2"),
            Paperwork(description="review #3")
        ])
        c1.employees = [e1, e2, b1, m1]

        e3 = Engineer(name="vlad", engineer_name="vlad", primary_language="cobol", status="elbonian engineer")
        c2.employees = [e3]
        sess = create_session()
        sess.save(c1)
        sess.save(c2)
        sess.flush()
        sess.clear()

        global all_employees, c1_employees, c2_employees
        all_employees = [e1, e2, b1, m1, e3]
        c1_employees = [e1, e2, b1, m1]
        c2_employees = [e3]

    def test_load_all(self):
        sess = create_session()

        self.assertEquals(sess.query(Person).all(), all_employees)


if __name__ == "__main__":
    testenv.main()