diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-04-23 22:17:25 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-04-23 22:17:25 -0400 |
| commit | cb3913a186a01d9425e0ba97de89aa6d7d64ab96 (patch) | |
| tree | 7616eade5c09cb0b6e833d8e881f795f4ea965f5 /examples | |
| parent | 841ea194bd7cf239323ee21320210fd6dc5c551d (diff) | |
| download | sqlalchemy-cb3913a186a01d9425e0ba97de89aa6d7d64ab96.tar.gz | |
- [feature] New standalone function with_polymorphic()
provides the functionality of query.with_polymorphic()
in a standalone form. It can be applied to any
entity within a query, including as the target
of a join in place of the "of_type()" modifier.
[ticket:2333]
- redo a large portion of the inheritance docs in terms
of declarative, new with_polymorphic() function
- upgrade examples/inheritance/polymorph, rename to "joined"
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/inheritance/joined.py | 135 | ||||
| -rw-r--r-- | examples/inheritance/polymorph.py | 125 |
2 files changed, 135 insertions, 125 deletions
diff --git a/examples/inheritance/joined.py b/examples/inheritance/joined.py new file mode 100644 index 000000000..aa4c18518 --- /dev/null +++ b/examples/inheritance/joined.py @@ -0,0 +1,135 @@ +"""this example illustrates a polymorphic load of two classes""" + +from sqlalchemy import Table, Column, Integer, String, \ + ForeignKey, create_engine, inspect, or_ +from sqlalchemy.orm import relationship, Session, with_polymorphic +from sqlalchemy.ext.declarative import declarative_base + +Base = declarative_base() + +class Company(Base): + __tablename__ = 'company' + id = Column(Integer, primary_key=True) + name = Column(String(50)) + + employees = relationship("Person", + backref='company', + cascade='all, delete-orphan') + + def __repr__(self): + return "Company %s" % self.name + +class Person(Base): + __tablename__ = 'person' + id = Column(Integer, primary_key=True) + company_id = Column(Integer, ForeignKey('company.id')) + name = Column(String(50)) + type = Column(String(50)) + + __mapper_args__ = { + 'polymorphic_identity':'person', + 'polymorphic_on':type + } + def __repr__(self): + return "Ordinary person %s" % self.name + +class Engineer(Person): + __tablename__ = 'engineer' + id = Column(Integer, ForeignKey('person.id'), primary_key=True) + status = Column(String(30)) + engineer_name = Column(String(30)) + primary_language = Column(String(30)) + + __mapper_args__ = { + 'polymorphic_identity':'engineer', + } + 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): + __tablename__ = 'manager' + id = Column(Integer, ForeignKey('person.id'), primary_key=True) + status = Column(String(30)) + manager_name = Column(String(30)) + + __mapper_args__ = { + 'polymorphic_identity':'manager', + } + def __repr__(self): + return "Manager %s, status %s, manager_name %s" % \ + (self.name, self.status, self.manager_name) + + +engine = create_engine('sqlite://', echo=True) +Base.metadata.create_all(engine) + +session = Session(engine) + +c = Company(name='company1', employees=[ + Manager( + name='pointy haired boss', + status='AAB', + manager_name='manager1'), + Engineer(name='dilbert', + status='BBA', + engineer_name='engineer1', + primary_language='java'), + Person(name='joesmith'), + Engineer(name='wally', + status='CGG', + engineer_name='engineer2', + primary_language='python'), + Manager(name='jsmith', + status='ABA', + manager_name='manager2') +]) +session.add(c) + +session.commit() + +c = session.query(Company).get(1) +for e in c.employees: + print e, inspect(e).key, e.company +assert set([e.name for e in c.employees]) == set(['pointy haired boss', + 'dilbert', 'joesmith', 'wally', 'jsmith']) +print "\n" + +dilbert = session.query(Person).filter_by(name='dilbert').one() +dilbert2 = session.query(Engineer).filter_by(name='dilbert').one() +assert dilbert is dilbert2 + +dilbert.engineer_name = 'hes dilbert!' + +session.commit() + +c = session.query(Company).get(1) +for e in c.employees: + print e + +# query using with_polymorphic. +eng_manager = with_polymorphic(Person, [Engineer, Manager], aliased=True) +print session.query(eng_manager).\ + filter( + or_(eng_manager.Engineer.engineer_name=='engineer1', + eng_manager.Manager.manager_name=='manager2' + ) + ).all() + +# illustrate join from Company, +# We use aliased=True +# to help when the selectable is used as the target of a join. +eng_manager = with_polymorphic(Person, [Engineer, Manager], aliased=True) +print session.query(Company).\ + join( + eng_manager, + Company.employees + ).filter( + or_(eng_manager.Engineer.engineer_name=='engineer1', + eng_manager.Manager.manager_name=='manager2') + ).all() + +session.commit() + diff --git a/examples/inheritance/polymorph.py b/examples/inheritance/polymorph.py deleted file mode 100644 index 316671bed..000000000 --- a/examples/inheritance/polymorph.py +++ /dev/null @@ -1,125 +0,0 @@ -from sqlalchemy import MetaData, Table, Column, Integer, String, \ - ForeignKey, create_engine -from sqlalchemy.orm import mapper, relationship, sessionmaker - - -# this example illustrates a polymorphic load of two classes - -metadata = MetaData() - -# a table to store companies -companies = Table('companies', metadata, - Column('company_id', Integer, primary_key=True), - Column('name', String(50))) - -# 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', metadata, - Column('person_id', Integer, 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)) - ) - -# create our classes. The Engineer and Manager classes extend from Person. -class Person(object): - def __init__(self, **kwargs): - for key, value in kwargs.iteritems(): - setattr(self, key, value) - 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 __init__(self, **kwargs): - for key, value in kwargs.iteritems(): - setattr(self, key, value) - def __repr__(self): - return "Company %s" % self.name - - -person_mapper = mapper(Person, people, polymorphic_on=people.c.type, - polymorphic_identity='person') -mapper(Engineer, engineers, inherits=person_mapper, - polymorphic_identity='engineer') -mapper(Manager, managers, inherits=person_mapper, - polymorphic_identity='manager') - -mapper(Company, companies, properties={'employees' - : relationship(Person, lazy='joined', backref='company', - cascade='all, delete-orphan')}) - -engine = create_engine('sqlite://', echo=True) - -metadata.create_all(engine) - -session = sessionmaker(engine)() - -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(Person(name='joesmith', status='HHH')) -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')) -session.add(c) - -session.commit() - -c = session.query(Company).get(1) -for e in c.employees: - print e, e._sa_instance_state.key, e.company -assert set([e.name for e in c.employees]) == set(['pointy haired boss', - 'dilbert', 'joesmith', 'wally', 'jsmith']) -print "\n" - -dilbert = session.query(Person).filter_by(name='dilbert').one() -dilbert2 = session.query(Engineer).filter_by(name='dilbert').one() -assert dilbert is dilbert2 - -dilbert.engineer_name = 'hes dibert!' - -session.commit() - -c = session.query(Company).get(1) -for e in c.employees: - print e - -# illustrate querying using direct table access: - -print session.query(Engineer.engineer_name).\ - select_from(engineers).\ - filter(Engineer.primary_language=='python').\ - all() - - -session.delete(c) -session.commit() - |
