summaryrefslogtreecommitdiff
path: root/examples/polymorph/polymorph2.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2006-03-24 06:28:27 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2006-03-24 06:28:27 +0000
commitb1deaf1fb76e2ed60da4bea5e1b5cc2b732b8a23 (patch)
treee2d02b4b610a4768c38749675f094fce6b444783 /examples/polymorph/polymorph2.py
parentcd39a0a78049f0e1978bc7990d7c677dbb891ac4 (diff)
downloadsqlalchemy-b1deaf1fb76e2ed60da4bea5e1b5cc2b732b8a23.tar.gz
some more tweaks to get more advanced polymorphic stuff to work
Diffstat (limited to 'examples/polymorph/polymorph2.py')
-rw-r--r--examples/polymorph/polymorph2.py137
1 files changed, 137 insertions, 0 deletions
diff --git a/examples/polymorph/polymorph2.py b/examples/polymorph/polymorph2.py
new file mode 100644
index 000000000..99ee6c34c
--- /dev/null
+++ b/examples/polymorph/polymorph2.py
@@ -0,0 +1,137 @@
+from sqlalchemy import *
+import sys
+
+# this example illustrates a polymorphic load of two classes, where each class has a very
+# different set of properties
+
+db = create_engine('sqlite://', echo=True, echo_uow=False)
+
+# a table to store companies
+companies = Table('companies', db,
+ Column('company_id', Integer, primary_key=True),
+ Column('name', String(50))).create()
+
+# we will define an inheritance relationship between the table "people" and "engineers",
+# and a second inheritance relationship between the table "people" and "managers"
+people = Table('people', db,
+ Column('person_id', Integer, primary_key=True),
+ Column('company_id', Integer, ForeignKey('companies.company_id')),
+ Column('name', String(50))).create()
+
+engineers = Table('engineers', db,
+ 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)),
+ ).create()
+
+managers = Table('managers', db,
+ Column('person_id', Integer, ForeignKey('people.person_id'), primary_key=True),
+ Column('status', String(30)),
+ Column('manager_name', String(50))
+ ).create()
+
+
+# create our classes. The Engineer and Manager classes extend from Person.
+class Person(object):
+ def __repr__(self):
+ return "Ordinary person %s" % self.name
+class Engineer(Person):
+ def __repr__(self):
+ return "Engineer %s, status %s, engineer_name %s, primary_language %s" % (self.name, self.status, self.engineer_name, self.primary_language)
+class Manager(Person):
+ def __repr__(self):
+ return "Manager %s, status %s, manager_name %s" % (self.name, self.status, self.manager_name)
+class Company(object):
+ def __repr__(self):
+ return "Company %s" % self.name
+
+# assign plain vanilla mappers
+assign_mapper(Person, people)
+assign_mapper(Engineer, engineers, inherits=Person.mapper)
+assign_mapper(Manager, managers, inherits=Person.mapper)
+
+# create a union that represents both types of joins. we have to use
+# nulls to pad out the disparate columns.
+person_join = select(
+ [
+ people,
+ managers.c.status,
+ managers.c.manager_name,
+ null().label('engineer_name'),
+ null().label('primary_language'),
+ column("'manager'").label('type')
+ ],
+ people.c.person_id==managers.c.person_id).union_all(
+ select(
+ [
+ people,
+ engineers.c.status,
+ null().label('').label('manager_name'),
+ engineers.c.engineer_name,
+ engineers.c.primary_language,
+ column("'engineer'").label('type')
+ ],
+ people.c.person_id==engineers.c.person_id)).alias('pjoin')
+
+
+# MapperExtension object.
+class PersonLoader(MapperExtension):
+ def create_instance(self, mapper, row, imap, class_):
+ if row[person_join.c.type] =='engineer':
+ return Engineer()
+ elif row[person_join.c.type] =='manager':
+ return Manager()
+ else:
+ return Person()
+
+ def populate_instance(self, mapper, instance, row, identitykey, imap, isnew):
+ if row[person_join.c.type] =='engineer':
+ Engineer.mapper.populate_instance(instance, row, identitykey, imap, isnew)
+ return False
+ elif row[person_join.c.type] =='manager':
+ Manager.mapper.populate_instance(instance, row, identitykey, imap, isnew)
+ return False
+ else:
+ return True
+
+
+
+people_mapper = mapper(Person, person_join, extension=PersonLoader())
+
+assign_mapper(Company, companies, properties={
+ 'employees': relation(people_mapper, lazy=False, private=True)
+})
+
+c = Company(name='company1')
+c.employees.append(Manager(name='pointy haired boss', status='AAB', manager_name='manager1'))
+c.employees.append(Engineer(name='dilbert', status='BBA', engineer_name='engineer1', primary_language='java'))
+c.employees.append(Engineer(name='wally', status='CGG', engineer_name='engineer2', primary_language='python'))
+c.employees.append(Manager(name='jsmith', status='ABA', manager_name='manager2'))
+objectstore.commit()
+
+objectstore.clear()
+
+c = Company.get(1)
+for e in c.employees:
+ print e, e._instance_key
+
+print "\n"
+
+dilbert = Engineer.mapper.get_by(name='dilbert')
+dilbert.engineer_name = 'hes dibert!'
+objectstore.commit()
+
+objectstore.clear()
+c = Company.get(1)
+for e in c.employees:
+ print e, e._instance_key
+
+objectstore.delete(c)
+objectstore.commit()
+
+
+managers.drop()
+engineers.drop()
+people.drop()
+companies.drop()