[Sqlalchemy-commits] sqlalchemy: - fix some unclear phrases in query regarding polymo...
Brought to you by:
zzzeek
From: <co...@sq...> - 2012-02-16 23:54:42
|
details: http://hg.sqlalchemy.org/sqlalchemy/sqlalchemy/rev/9d858779c963 changeset: 8115:9d858779c963 user: Mike Bayer <mi...@zz...> date: Thu Feb 16 18:54:10 2012 -0500 description: - fix some unclear phrases in query regarding polymorphic, slowly approaching [ticket:2333] - pep8 most of the big old polymorphic tests, break lots of the inheritance/test_query tests into individual tests since these are the ones that are easily broken when screwing with query diffstat: lib/sqlalchemy/orm/query.py | 34 +- test/orm/inheritance/test_assorted_poly.py | 1454 +++++++++++++++++ test/orm/inheritance/test_poly_persistence.py | 347 ++++ test/orm/inheritance/test_polymorph.py | 291 --- test/orm/inheritance/test_polymorph2.py | 1266 -------------- test/orm/inheritance/test_polymorphic_rel.py | 1579 ++++++++++++++++++ test/orm/inheritance/test_query.py | 2136 ------------------------- test/orm/inheritance/test_relationship.py | 877 ++++++++++ 8 files changed, 4273 insertions(+), 3711 deletions(-) diffs (truncated from 8087 to 300 lines): diff -r ecff13f0023e -r 9d858779c963 lib/sqlalchemy/orm/query.py --- a/lib/sqlalchemy/orm/query.py Thu Feb 16 10:04:07 2012 -0500 +++ b/lib/sqlalchemy/orm/query.py Thu Feb 16 18:54:10 2012 -0500 @@ -133,7 +133,7 @@ with_polymorphic = mapper._with_polymorphic_mappers if mapper.mapped_table not in \ self._polymorphic_adapters: - self.__mapper_loads_polymorphically_with(mapper, + self._mapper_loads_polymorphically_with(mapper, sql_util.ColumnAdapter( selectable, mapper._equivalent_columns)) @@ -150,7 +150,7 @@ is_aliased_class, with_polymorphic) ent.setup_entity(entity, *d[entity]) - def __mapper_loads_polymorphically_with(self, mapper, adapter): + def _mapper_loads_polymorphically_with(self, mapper, adapter): for m2 in mapper._with_polymorphic_mappers: self._polymorphic_adapters[m2] = adapter for m in m2.iterate_to_root(): @@ -174,10 +174,6 @@ self._from_obj_alias = sql_util.ColumnAdapter( self._from_obj[0], equivs) - def _get_polymorphic_adapter(self, entity, selectable): - self.__mapper_loads_polymorphically_with(entity.mapper, - sql_util.ColumnAdapter(selectable, - entity.mapper._equivalent_columns)) def _reset_polymorphic_adapter(self, mapper): for m2 in mapper._with_polymorphic_mappers: @@ -325,13 +321,6 @@ ) return self._entity_zero() - def _generate_mapper_zero(self): - if not getattr(self._entities[0], 'primary_entity', False): - raise sa_exc.InvalidRequestError( - "No primary mapper set up for this Query.") - entity = self._entities[0]._clone() - self._entities = [entity] + self._entities[1:] - return entity def __all_equivs(self): equivs = {} @@ -602,7 +591,12 @@ such as concrete table mappers. """ - entity = self._generate_mapper_zero() + + if not getattr(self._entities[0], 'primary_entity', False): + raise sa_exc.InvalidRequestError( + "No primary mapper set up for this Query.") + entity = self._entities[0]._clone() + self._entities = [entity] + self._entities[1:] entity.set_with_polymorphic(self, cls_or_mappers, selectable=selectable, @@ -1584,7 +1578,6 @@ consistent format with which to form the actual JOIN constructs. """ - self._polymorphic_adapters = self._polymorphic_adapters.copy() if not from_joinpoint: self._reset_joinpoint() @@ -1684,6 +1677,8 @@ onclause, outerjoin, create_aliases, prop): """append a JOIN to the query's from clause.""" + self._polymorphic_adapters = self._polymorphic_adapters.copy() + if left is None: if self._from_obj: left = self._from_obj[0] @@ -1759,7 +1754,8 @@ # until reset_joinpoint() is called. if need_adapter: self._filter_aliases = ORMAdapter(right, - equivalents=right_mapper and right_mapper._equivalent_columns or {}, + equivalents=right_mapper and + right_mapper._equivalent_columns or {}, chain_to=self._filter_aliases) # if the onclause is a ClauseElement, adapt it with any @@ -1772,7 +1768,7 @@ # ensure that columns retrieved from this target in the result # set are also adapted. if aliased_entity and not create_aliases: - self.__mapper_loads_polymorphically_with( + self._mapper_loads_polymorphically_with( right_mapper, ORMAdapter( right, @@ -2960,7 +2956,9 @@ # with_polymorphic() can be applied to aliases if not self.is_aliased_class: self.selectable = from_obj - self.adapter = query._get_polymorphic_adapter(self, from_obj) + query._mapper_loads_polymorphically_with(self.mapper, + sql_util.ColumnAdapter(from_obj, + self.mapper._equivalent_columns)) filter_fn = id diff -r ecff13f0023e -r 9d858779c963 test/orm/inheritance/test_assorted_poly.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/orm/inheritance/test_assorted_poly.py Thu Feb 16 18:54:10 2012 -0500 @@ -0,0 +1,1454 @@ +"""Very old inheritance-related tests. + + +""" + +from test.lib.testing import eq_ +from sqlalchemy import * +from sqlalchemy import util +from sqlalchemy.orm import * +from sqlalchemy.orm.interfaces import MANYTOONE +from test.lib import AssertsExecutionResults, testing +from test.lib.util import function_named +from test.lib import fixtures +from test.orm import _fixtures +from test.lib.testing import eq_ +from test.lib.schema import Table, Column + +class AttrSettable(object): + def __init__(self, **kwargs): + [setattr(self, k, v) for k, v in kwargs.iteritems()] + def __repr__(self): + return self.__class__.__name__ + "(%s)" % (hex(id(self))) + + +class RelationshipTest1(fixtures.MappedTest): + """test self-referential relationships on polymorphic mappers""" + @classmethod + def define_tables(cls, metadata): + global people, managers + + people = Table('people', metadata, + Column('person_id', Integer, Sequence('person_id_seq', + optional=True), + primary_key=True), + Column('manager_id', Integer, + ForeignKey('managers.person_id', + use_alter=True, name="mpid_fq")), + Column('name', String(50)), + Column('type', String(30))) + + managers = Table('managers', metadata, + Column('person_id', Integer, ForeignKey('people.person_id'), + primary_key=True), + Column('status', String(30)), + Column('manager_name', String(50)) + ) + + def teardown(self): + people.update(values={people.c.manager_id:None}).execute() + super(RelationshipTest1, self).teardown() + + def test_parent_refs_descendant(self): + class Person(AttrSettable): + pass + class Manager(Person): + pass + + mapper(Person, people, properties={ + 'manager':relationship(Manager, primaryjoin=( + people.c.manager_id == + managers.c.person_id), + uselist=False, post_update=True) + }) + mapper(Manager, managers, inherits=Person, + inherit_condition=people.c.person_id==managers.c.person_id) + + eq_(class_mapper(Person).get_property('manager').synchronize_pairs, + [(managers.c.person_id,people.c.manager_id)]) + + session = create_session() + p = Person(name='some person') + m = Manager(name='some manager') + p.manager = m + session.add(p) + session.flush() + session.expunge_all() + + p = session.query(Person).get(p.person_id) + m = session.query(Manager).get(m.person_id) + assert p.manager is m + + def test_descendant_refs_parent(self): + class Person(AttrSettable): + pass + class Manager(Person): + pass + + mapper(Person, people) + mapper(Manager, managers, inherits=Person, + inherit_condition=people.c.person_id== + managers.c.person_id, + properties={ + 'employee':relationship(Person, primaryjoin=( + people.c.manager_id == + managers.c.person_id), + foreign_keys=[people.c.manager_id], + uselist=False, post_update=True) + }) + + session = create_session() + p = Person(name='some person') + m = Manager(name='some manager') + m.employee = p + session.add(m) + session.flush() + session.expunge_all() + + p = session.query(Person).get(p.person_id) + m = session.query(Manager).get(m.person_id) + assert m.employee is p + +class RelationshipTest2(fixtures.MappedTest): + """test self-referential relationships on polymorphic mappers""" + @classmethod + def define_tables(cls, metadata): + global people, managers, data + people = Table('people', metadata, + Column('person_id', Integer, primary_key=True, + test_needs_autoincrement=True), + Column('name', String(50)), + Column('type', String(30))) + + managers = Table('managers', metadata, + Column('person_id', Integer, ForeignKey('people.person_id'), + primary_key=True), + Column('manager_id', Integer, ForeignKey('people.person_id')), + Column('status', String(30)), + ) + + data = Table('data', metadata, + Column('person_id', Integer, ForeignKey('managers.person_id'), + primary_key=True), + Column('data', String(30)) + ) + + def testrelationshiponsubclass_j1_nodata(self): + self.do_test("join1", False) + def testrelationshiponsubclass_j2_nodata(self): + self.do_test("join2", False) + def testrelationshiponsubclass_j1_data(self): + self.do_test("join1", True) + def testrelationshiponsubclass_j2_data(self): + self.do_test("join2", True) + def testrelationshiponsubclass_j3_nodata(self): + self.do_test("join3", False) + def testrelationshiponsubclass_j3_data(self): + self.do_test("join3", True) + + def do_test(self, jointype="join1", usedata=False): + class Person(AttrSettable): + pass + class Manager(Person): + pass + + if jointype == "join1": + poly_union = polymorphic_union({ + 'person':people.select(people.c.type=='person'), + 'manager':join(people, managers, + people.c.person_id==managers.c.person_id) + }, None) + polymorphic_on=poly_union.c.type + elif jointype == "join2": + poly_union = polymorphic_union({ + 'person':people.select(people.c.type=='person'), + 'manager':managers.join(people, + people.c.person_id==managers.c.person_id) + }, None) + polymorphic_on=poly_union.c.type + elif jointype == "join3": + poly_union = None + polymorphic_on = people.c.type + + if usedata: + class Data(object): + def __init__(self, data): + self.data = data + mapper(Data, data) + + mapper(Person, people, + with_polymorphic=('*', poly_union), + polymorphic_identity='person', + polymorphic_on=polymorphic_on) + + if usedata: + mapper(Manager, managers, + inherits=Person, + inherit_condition=people.c.person_id== + managers.c.person_id, + polymorphic_identity='manager', |