1
from sqlalchemy import MetaData, Table, Column, Integer, String, \
2
ForeignKey, create_engine
3
from sqlalchemy.orm import mapper, relationship, sessionmaker
6
# this example illustrates a polymorphic load of two classes
10
# a table to store companies
11
companies = Table('companies', metadata,
12
Column('company_id', Integer, primary_key=True),
13
Column('name', String(50)))
15
# we will define an inheritance relationship between the table "people" and
16
# "engineers", and a second inheritance relationship between the table
17
# "people" and "managers"
18
people = Table('people', metadata,
19
Column('person_id', Integer, primary_key=True),
20
Column('company_id', Integer, ForeignKey('companies.company_id')),
21
Column('name', String(50)),
22
Column('type', String(30)))
24
engineers = Table('engineers', metadata,
25
Column('person_id', Integer, ForeignKey('people.person_id'),
27
Column('status', String(30)),
28
Column('engineer_name', String(50)),
29
Column('primary_language', String(50)),
32
managers = Table('managers', metadata,
33
Column('person_id', Integer, ForeignKey('people.person_id'),
35
Column('status', String(30)),
36
Column('manager_name', String(50))
39
# create our classes. The Engineer and Manager classes extend from Person.
41
def __init__(self, **kwargs):
42
for key, value in kwargs.iteritems():
43
setattr(self, key, value)
45
return "Ordinary person %s" % self.name
46
class Engineer(Person):
48
return "Engineer %s, status %s, engineer_name %s, "\
49
"primary_language %s" % \
50
(self.name, self.status,
51
self.engineer_name, self.primary_language)
52
class Manager(Person):
54
return "Manager %s, status %s, manager_name %s" % \
55
(self.name, self.status, self.manager_name)
56
class Company(object):
57
def __init__(self, **kwargs):
58
for key, value in kwargs.iteritems():
59
setattr(self, key, value)
61
return "Company %s" % self.name
64
person_mapper = mapper(Person, people, polymorphic_on=people.c.type,
65
polymorphic_identity='person')
66
mapper(Engineer, engineers, inherits=person_mapper,
67
polymorphic_identity='engineer')
68
mapper(Manager, managers, inherits=person_mapper,
69
polymorphic_identity='manager')
71
mapper(Company, companies, properties={'employees'
72
: relationship(Person, lazy='joined', backref='company',
73
cascade='all, delete-orphan')})
75
engine = create_engine('sqlite://', echo=True)
77
metadata.create_all(engine)
79
session = sessionmaker(engine)()
81
c = Company(name='company1')
82
c.employees.append(Manager(name='pointy haired boss', status='AAB',
83
manager_name='manager1'))
84
c.employees.append(Engineer(name='dilbert', status='BBA',
85
engineer_name='engineer1', primary_language='java'))
86
c.employees.append(Person(name='joesmith', status='HHH'))
87
c.employees.append(Engineer(name='wally', status='CGG',
88
engineer_name='engineer2', primary_language='python'
90
c.employees.append(Manager(name='jsmith', status='ABA',
91
manager_name='manager2'))
96
c = session.query(Company).get(1)
98
print e, e._sa_instance_state.key, e.company
99
assert set([e.name for e in c.employees]) == set(['pointy haired boss',
100
'dilbert', 'joesmith', 'wally', 'jsmith'])
103
dilbert = session.query(Person).filter_by(name='dilbert').one()
104
dilbert2 = session.query(Engineer).filter_by(name='dilbert').one()
105
assert dilbert is dilbert2
107
dilbert.engineer_name = 'hes dibert!'
111
c = session.query(Company).get(1)
112
for e in c.employees:
115
# illustrate querying using direct table access:
117
print session.query(Engineer.engineer_name).\
118
select_from(engineers).\
119
filter(Engineer.primary_language=='python').\