diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2006-03-24 06:28:27 +0000 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2006-03-24 06:28:27 +0000 |
| commit | b1deaf1fb76e2ed60da4bea5e1b5cc2b732b8a23 (patch) | |
| tree | e2d02b4b610a4768c38749675f094fce6b444783 /examples/polymorph/polymorph2.py | |
| parent | cd39a0a78049f0e1978bc7990d7c677dbb891ac4 (diff) | |
| download | sqlalchemy-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.py | 137 |
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() |
