diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2006-03-06 03:10:46 +0000 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2006-03-06 03:10:46 +0000 |
| commit | 1644a44628f6a09bb992752bf266994afe0e98df (patch) | |
| tree | 515a7c6709fe292af63319d6e1e2ba04349b0bf5 /examples | |
| parent | a0079b6831aef2b604859f89f07772e65c04d5d4 (diff) | |
| download | sqlalchemy-1644a44628f6a09bb992752bf266994afe0e98df.tar.gz | |
a mapper with inheritance will place itself as "dependent" on the inherited mapper; even though this is not usually needed, it allows certain exotic combinations of mapper setups to work (i.e. the one in the polymorph example)
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/polymorph/polymorph.py | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/examples/polymorph/polymorph.py b/examples/polymorph/polymorph.py index b19038016..7200aa016 100644 --- a/examples/polymorph/polymorph.py +++ b/examples/polymorph/polymorph.py @@ -6,7 +6,8 @@ import sys # extend from a common base class, although this same approach can be used # with -db = create_engine('sqlite://', echo=True, echo_uow=False) +#db = create_engine('sqlite://', echo=True, echo_uow=False) +db = create_engine('postgres://user=scott&password=tiger&host=127.0.0.1&database=test', echo=True, echo_uow=False) # a table to store companies companies = Table('companies', db, @@ -52,9 +53,10 @@ assign_mapper(Engineer, engineers, inherits=Person.mapper) assign_mapper(Manager, managers, inherits=Person.mapper) # next, we define a query that is going to load Managers and Engineers in one shot. -# this query is tricky since the managers and engineers tables contain the same "description" column, -# so we set up a full blown select() statement that uses aliases for the description -# column. The select() statement is also given an alias 'pjoin', since the mapper requires +# we will use a UNION ALL with an extra hardcoded column to indicate the type of object. +# this can also be done via several LEFT OUTER JOINS but a UNION is more appropriate +# since they are distinct result sets. +# The select() statement is also given an alias 'pjoin', since the mapper requires # that all Selectables have a name. # # TECHNIQUE - when you want to load a certain set of objects from a in one query, all the @@ -65,7 +67,7 @@ assign_mapper(Manager, managers, inherits=Person.mapper) # person_join = select( [people, managers.c.description,column("'manager'").label('type')], - people.c.person_id==managers.c.person_id).union( + people.c.person_id==managers.c.person_id).union_all( select( [people, engineers.c.description, column("'engineer'").label('type')], people.c.person_id==engineers.c.person_id)).alias('pjoin') @@ -89,20 +91,24 @@ class PersonLoader(MapperExtension): ext = PersonLoader() # set up the polymorphic mapper, which maps the person_join we set up to -# the Person class, using an instance of PersonLoader. Note that even though -# this mapper is against Person, its not going to screw up the normal operation -# of the Person object since its not the "primary" mapper. In reality, we could even -# make this mapper against some other class we dont care about since the creation of -# objects is hardcoded. +# the Person class, using an instance of PersonLoader. people_mapper = mapper(Person, person_join, extension=ext) +# create a mapper for Company. the 'employees' relationship points to +# our new people_mapper. +# +# the dependency relationships which take effect on commit (i.e. the order of +# inserts/deletes) will be established against the Person class's primary +# mapper, and when the Engineer and +# Manager objects are found in the 'employees' list, the primary mappers +# for those subclasses will register +# themselves as dependent on the Person mapper's save operations. +# (translation: it'll work) +# TODO: get the eager loading to work (the compound select alias doesnt like being aliased itself) assign_mapper(Company, companies, properties={ - 'employees': relation(people_mapper), - 'engineers': relation(Engineer, private=True), - 'managers':relation(Manager, private=True) + 'employees': relation(people_mapper, private=True) }) - c = Company(name='company1') c.employees.append(Manager(name='pointy haired boss', description='manager1')) c.employees.append(Engineer(name='dilbert', description='engineer1')) @@ -128,4 +134,10 @@ for e in c.employees: print e, e._instance_key objectstore.delete(c) -objectstore.commit()
\ No newline at end of file +objectstore.commit() + + +managers.drop() +engineers.drop() +people.drop() +companies.drop() |
