Exemple #1
0
    def test_relationship(self):
        pjoin = polymorphic_union(
            {
                "manager": managers_table,
                "engineer": engineers_table
            },
            "type",
            "pjoin",
        )
        mapper(
            Company,
            companies,
            properties={"employees": relationship(Employee)},
        )
        employee_mapper = mapper(Employee, pjoin, polymorphic_on=pjoin.c.type)
        mapper(
            Manager,
            managers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="manager",
        )
        mapper(
            Engineer,
            engineers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="engineer",
        )
        session = create_session()
        c = Company()
        c.employees.append(Manager("Tom", "knows how to manage things"))
        c.employees.append(Engineer("Kurt", "knows how to hack"))
        session.add(c)
        session.flush()
        session.expunge_all()

        def go():
            c2 = session.query(Company).get(c.id)
            assert set([repr(x) for x in c2.employees]) == set([
                "Engineer Kurt knows how to hack",
                "Manager Tom knows how to manage things",
            ])

        self.assert_sql_count(testing.db, go, 2)
        session.expunge_all()

        def go():
            c2 = (session.query(Company).options(joinedload(
                Company.employees)).get(c.id))
            assert set([repr(x) for x in c2.employees]) == set([
                "Engineer Kurt knows how to hack",
                "Manager Tom knows how to manage things",
            ])

        self.assert_sql_count(testing.db, go, 1)
Exemple #2
0
    def test_keys(self):
        pjoin = polymorphic_union(
            {
                "refugee": refugees_table,
                "office": offices_table
            },
            "type",
            "pjoin",
        )

        class Location(object):
            pass

        class Refugee(Location):
            pass

        class Office(Location):
            pass

        location_mapper = mapper(
            Location,
            pjoin,
            polymorphic_on=pjoin.c.type,
            polymorphic_identity="location",
        )
        mapper(
            Office,
            offices_table,
            inherits=location_mapper,
            concrete=True,
            polymorphic_identity="office",
        )
        mapper(
            Refugee,
            refugees_table,
            inherits=location_mapper,
            concrete=True,
            polymorphic_identity="refugee",
        )
        sess = create_session()
        eq_(sess.query(Refugee).get(1).name, "refugee1")
        eq_(sess.query(Refugee).get(2).name, "refugee2")
        eq_(sess.query(Office).get(1).name, "office1")
        eq_(sess.query(Office).get(2).name, "office2")
Exemple #3
0
 def test_basic(self):
     pjoin = polymorphic_union(
         {
             "manager": managers_table,
             "engineer": engineers_table
         },
         "type",
         "pjoin",
     )
     employee_mapper = mapper(Employee, pjoin, polymorphic_on=pjoin.c.type)
     mapper(
         Manager,
         managers_table,
         inherits=employee_mapper,
         concrete=True,
         polymorphic_identity="manager",
     )
     mapper(
         Engineer,
         engineers_table,
         inherits=employee_mapper,
         concrete=True,
         polymorphic_identity="engineer",
     )
     session = create_session()
     session.add(Manager("Tom", "knows how to manage things"))
     session.add(Engineer("Kurt", "knows how to hack"))
     session.flush()
     session.expunge_all()
     assert set([repr(x) for x in session.query(Employee)]) == set([
         "Engineer Kurt knows how to hack",
         "Manager Tom knows how to manage things",
     ])
     assert set([repr(x) for x in session.query(Manager)
                 ]) == set(["Manager Tom knows how to manage things"])
     assert set([repr(x) for x in session.query(Engineer)
                 ]) == set(["Engineer Kurt knows how to hack"])
     manager = session.query(Manager).one()
     session.expire(manager, ["manager_data"])
     eq_(manager.manager_data, "knows how to manage things")
    def _get_polymorphics(cls):
        people, engineers, managers, boss = (
            cls.tables.people,
            cls.tables.engineers,
            cls.tables.managers,
            cls.tables.boss,
        )

        person_join = polymorphic_union(
            util.OrderedDict(
                [
                    ("engineer", people.join(engineers)),
                    ("manager", people.join(managers)),
                ]
            ),
            None,
            "pjoin",
        )
        manager_join = people.join(managers).outerjoin(boss)
        person_with_polymorphic = ([Person, Manager, Engineer], person_join)
        manager_with_polymorphic = ("*", manager_join)
        return person_with_polymorphic, manager_with_polymorphic
Exemple #5
0
        def test_roundtrip(self):
            parent_table = {"a": ta, "b": tb, "c": tc}[parent]
            child_table = {"a": ta, "b": tb, "c": tc}[child]

            remote_side = None

            if direction == MANYTOONE:
                foreign_keys = [parent_table.c.child_id]
            elif direction == ONETOMANY:
                foreign_keys = [child_table.c.parent_id]

            atob = ta.c.id == tb.c.id
            btoc = tc.c.id == tb.c.id

            if direction == ONETOMANY:
                relationshipjoin = parent_table.c.id == child_table.c.parent_id
            elif direction == MANYTOONE:
                relationshipjoin = parent_table.c.child_id == child_table.c.id
                if parent is child:
                    remote_side = [child_table.c.id]

            abcjoin = polymorphic_union(
                {
                    "a":
                    ta.select(
                        tb.c.id == None,  # noqa
                        from_obj=[ta.outerjoin(tb, onclause=atob)],
                    ),
                    "b":
                    ta.join(tb, onclause=atob).outerjoin(
                        tc, onclause=btoc).select(
                            tc.c.id == None).reduce_columns(),  # noqa
                    "c":
                    tc.join(tb, onclause=btoc).join(ta, onclause=atob),
                },
                "type",
                "abcjoin",
            )

            bcjoin = polymorphic_union(
                {
                    "b":
                    ta.join(tb, onclause=atob).outerjoin(
                        tc, onclause=btoc).select(
                            tc.c.id == None).reduce_columns(),  # noqa
                    "c":
                    tc.join(tb, onclause=btoc).join(ta, onclause=atob),
                },
                "type",
                "bcjoin",
            )

            class A(object):
                def __init__(self, name):
                    self.a_data = name

            class B(A):
                pass

            class C(B):
                pass

            mapper(
                A,
                ta,
                polymorphic_on=abcjoin.c.type,
                with_polymorphic=("*", abcjoin),
                polymorphic_identity="a",
            )
            mapper(
                B,
                tb,
                polymorphic_on=bcjoin.c.type,
                with_polymorphic=("*", bcjoin),
                polymorphic_identity="b",
                inherits=A,
                inherit_condition=atob,
            )
            mapper(
                C,
                tc,
                polymorphic_identity="c",
                inherits=B,
                inherit_condition=btoc,
            )

            parent_mapper = class_mapper({ta: A, tb: B, tc: C}[parent_table])
            child_mapper = class_mapper({ta: A, tb: B, tc: C}[child_table])

            parent_class = parent_mapper.class_
            child_class = child_mapper.class_

            parent_mapper.add_property(
                "collection",
                relationship(
                    child_mapper,
                    primaryjoin=relationshipjoin,
                    foreign_keys=foreign_keys,
                    order_by=child_mapper.c.id,
                    remote_side=remote_side,
                    uselist=True,
                ),
            )

            sess = create_session()

            parent_obj = parent_class("parent1")
            child_obj = child_class("child1")
            somea = A("somea")
            someb = B("someb")
            somec = C("somec")

            # print "APPENDING", parent.__class__.__name__ , "TO",
            # child.__class__.__name__

            sess.add(parent_obj)
            parent_obj.collection.append(child_obj)
            if direction == ONETOMANY:
                child2 = child_class("child2")
                parent_obj.collection.append(child2)
                sess.add(child2)
            elif direction == MANYTOONE:
                parent2 = parent_class("parent2")
                parent2.collection.append(child_obj)
                sess.add(parent2)
            sess.add(somea)
            sess.add(someb)
            sess.add(somec)
            sess.flush()
            sess.expunge_all()

            # assert result via direct get() of parent object
            result = sess.query(parent_class).get(parent_obj.id)
            assert result.id == parent_obj.id
            assert result.collection[0].id == child_obj.id
            if direction == ONETOMANY:
                assert result.collection[1].id == child2.id
            elif direction == MANYTOONE:
                result2 = sess.query(parent_class).get(parent2.id)
                assert result2.id == parent2.id
                assert result2.collection[0].id == child_obj.id

            sess.expunge_all()

            # assert result via polymorphic load of parent object
            result = sess.query(A).filter_by(id=parent_obj.id).one()
            assert result.id == parent_obj.id
            assert result.collection[0].id == child_obj.id
            if direction == ONETOMANY:
                assert result.collection[1].id == child2.id
            elif direction == MANYTOONE:
                result2 = sess.query(A).filter_by(id=parent2.id).one()
                assert result2.id == parent2.id
                assert result2.collection[0].id == child_obj.id
    def _setup_mapping(self, use_unions, use_joins):
        (
            Publication,
            Issue,
            Location,
            LocationName,
            PageSize,
            Magazine,
            Page,
            MagazinePage,
            ClassifiedPage,
        ) = self.classes(
            "Publication",
            "Issue",
            "Location",
            "LocationName",
            "PageSize",
            "Magazine",
            "Page",
            "MagazinePage",
            "ClassifiedPage",
        )
        mapper(Publication, self.tables.publication)

        mapper(
            Issue,
            self.tables.issue,
            properties={
                "publication": relationship(
                    Publication,
                    backref=backref("issues", cascade="all, delete-orphan"),
                )
            },
        )

        mapper(LocationName, self.tables.location_name)

        mapper(
            Location,
            self.tables.location,
            properties={
                "issue": relationship(
                    Issue,
                    backref=backref(
                        "locations",
                        lazy="joined",
                        cascade="all, delete-orphan",
                    ),
                ),
                "name": relationship(LocationName),
            },
        )

        mapper(PageSize, self.tables.page_size)

        mapper(
            Magazine,
            self.tables.magazine,
            properties={
                "location": relationship(
                    Location, backref=backref("magazine", uselist=False)
                ),
                "size": relationship(PageSize),
            },
        )

        if use_unions:
            page_join = polymorphic_union(
                {
                    "m": self.tables.page.join(self.tables.magazine_page),
                    "c": self.tables.page.join(self.tables.magazine_page).join(
                        self.tables.classified_page
                    ),
                    "p": self.tables.page.select(
                        self.tables.page.c.type == "p"
                    ),
                },
                None,
                "page_join",
            )
            page_mapper = mapper(
                Page,
                self.tables.page,
                with_polymorphic=("*", page_join),
                polymorphic_on=page_join.c.type,
                polymorphic_identity="p",
            )
        elif use_joins:
            page_join = self.tables.page.outerjoin(
                self.tables.magazine_page
            ).outerjoin(self.tables.classified_page)
            page_mapper = mapper(
                Page,
                self.tables.page,
                with_polymorphic=("*", page_join),
                polymorphic_on=self.tables.page.c.type,
                polymorphic_identity="p",
            )
        else:
            page_mapper = mapper(
                Page,
                self.tables.page,
                polymorphic_on=self.tables.page.c.type,
                polymorphic_identity="p",
            )

        if use_unions:
            magazine_join = polymorphic_union(
                {
                    "m": self.tables.page.join(self.tables.magazine_page),
                    "c": self.tables.page.join(self.tables.magazine_page).join(
                        self.tables.classified_page
                    ),
                },
                None,
                "page_join",
            )
            magazine_page_mapper = mapper(
                MagazinePage,
                self.tables.magazine_page,
                with_polymorphic=("*", magazine_join),
                inherits=page_mapper,
                polymorphic_identity="m",
                properties={
                    "magazine": relationship(
                        Magazine,
                        backref=backref(
                            "pages", order_by=magazine_join.c.page_no
                        ),
                    )
                },
            )
        elif use_joins:
            magazine_join = self.tables.page.join(
                self.tables.magazine_page
            ).outerjoin(self.tables.classified_page)
            magazine_page_mapper = mapper(
                MagazinePage,
                self.tables.magazine_page,
                with_polymorphic=("*", magazine_join),
                inherits=page_mapper,
                polymorphic_identity="m",
                properties={
                    "magazine": relationship(
                        Magazine,
                        backref=backref(
                            "pages", order_by=self.tables.page.c.page_no
                        ),
                    )
                },
            )
        else:
            magazine_page_mapper = mapper(
                MagazinePage,
                self.tables.magazine_page,
                inherits=page_mapper,
                polymorphic_identity="m",
                properties={
                    "magazine": relationship(
                        Magazine,
                        backref=backref(
                            "pages", order_by=self.tables.page.c.page_no
                        ),
                    )
                },
            )

        mapper(
            ClassifiedPage,
            self.tables.classified_page,
            inherits=magazine_page_mapper,
            polymorphic_identity="c",
            primary_key=[self.tables.page.c.id],
        )
Exemple #7
0
    def test_merge_w_relationship(self):
        A, C, B, c_table, b_table, a_table, Dest, dest_table = (
            self.classes.A,
            self.classes.C,
            self.classes.B,
            self.tables.c_table,
            self.tables.b_table,
            self.tables.a_table,
            self.classes.Dest,
            self.tables.dest_table,
        )

        ajoin = polymorphic_union({
            "a": a_table,
            "b": b_table,
            "c": c_table
        }, "type", "ajoin")
        mapper(
            A,
            a_table,
            with_polymorphic=("*", ajoin),
            polymorphic_on=ajoin.c.type,
            polymorphic_identity="a",
            properties={
                "some_dest": relationship(Dest, back_populates="many_a")
            },
        )
        mapper(
            B,
            b_table,
            inherits=A,
            concrete=True,
            polymorphic_identity="b",
            properties={
                "some_dest": relationship(Dest, back_populates="many_a")
            },
        )

        mapper(
            C,
            c_table,
            inherits=A,
            concrete=True,
            polymorphic_identity="c",
            properties={
                "some_dest": relationship(Dest, back_populates="many_a")
            },
        )

        mapper(
            Dest,
            dest_table,
            properties={
                "many_a":
                relationship(A,
                             back_populates="some_dest",
                             order_by=ajoin.c.id)
            },
        )

        assert C.some_dest.property.parent is class_mapper(C)
        assert B.some_dest.property.parent is class_mapper(B)
        assert A.some_dest.property.parent is class_mapper(A)

        sess = sessionmaker()()
        dest1 = Dest(name="d1")
        dest2 = Dest(name="d2")
        a1 = A(some_dest=dest2, aname="a1")
        b1 = B(some_dest=dest1, bname="b1")
        c1 = C(some_dest=dest2, cname="c1")
        sess.add_all([dest1, dest2, c1, a1, b1])
        sess.commit()

        sess2 = sessionmaker()()
        merged_c1 = sess2.merge(c1)
        eq_(merged_c1.some_dest.name, "d2")
        eq_(merged_c1.some_dest_id, c1.some_dest_id)
Exemple #8
0
    def test_polymorphic_backref(self):
        """test multiple backrefs to the same polymorphically-loading
        attribute."""

        A, C, B, c_table, b_table, a_table, Dest, dest_table = (
            self.classes.A,
            self.classes.C,
            self.classes.B,
            self.tables.c_table,
            self.tables.b_table,
            self.tables.a_table,
            self.classes.Dest,
            self.tables.dest_table,
        )

        ajoin = polymorphic_union({
            "a": a_table,
            "b": b_table,
            "c": c_table
        }, "type", "ajoin")
        mapper(
            A,
            a_table,
            with_polymorphic=("*", ajoin),
            polymorphic_on=ajoin.c.type,
            polymorphic_identity="a",
            properties={
                "some_dest": relationship(Dest, back_populates="many_a")
            },
        )
        mapper(
            B,
            b_table,
            inherits=A,
            concrete=True,
            polymorphic_identity="b",
            properties={
                "some_dest": relationship(Dest, back_populates="many_a")
            },
        )

        mapper(
            C,
            c_table,
            inherits=A,
            concrete=True,
            polymorphic_identity="c",
            properties={
                "some_dest": relationship(Dest, back_populates="many_a")
            },
        )

        mapper(
            Dest,
            dest_table,
            properties={
                "many_a":
                relationship(A,
                             back_populates="some_dest",
                             order_by=ajoin.c.id)
            },
        )

        sess = sessionmaker()()
        dest1 = Dest(name="c1")
        dest2 = Dest(name="c2")
        a1 = A(some_dest=dest1, aname="a1", id=1)
        a2 = A(some_dest=dest2, aname="a2", id=2)
        b1 = B(some_dest=dest1, bname="b1", id=3)
        b2 = B(some_dest=dest1, bname="b2", id=4)
        c1 = C(some_dest=dest1, cname="c1", id=5)
        c2 = C(some_dest=dest2, cname="c2", id=6)

        eq_([a2, c2], dest2.many_a)
        eq_([a1, b1, b2, c1], dest1.many_a)
        sess.add_all([dest1, dest2])
        sess.commit()

        assert sess.query(Dest).filter(Dest.many_a.contains(a2)).one() is dest2
        assert sess.query(Dest).filter(Dest.many_a.contains(b1)).one() is dest1
        assert sess.query(Dest).filter(Dest.many_a.contains(c2)).one() is dest2

        eq_(dest2.many_a, [a2, c2])
        eq_(dest1.many_a, [a1, b1, b2, c1])
        sess.expire_all()

        def go():
            eq_(
                [
                    Dest(many_a=[
                        A(aname="a1"),
                        B(bname="b1"),
                        B(bname="b2"),
                        C(cname="c1"),
                    ]),
                    Dest(many_a=[A(aname="a2"), C(cname="c2")]),
                ],
                sess.query(Dest).options(joinedload(Dest.many_a)).order_by(
                    Dest.id).all(),
            )

        self.assert_sql_count(testing.db, go, 1)
Exemple #9
0
    def test_without_default_polymorphic(self):
        pjoin = polymorphic_union(
            {
                "employee": employees_table,
                "manager": managers_table,
                "engineer": engineers_table,
                "hacker": hackers_table,
            },
            "type",
            "pjoin",
        )
        pjoin2 = polymorphic_union(
            {
                "engineer": engineers_table,
                "hacker": hackers_table
            },
            "type",
            "pjoin2",
        )
        employee_mapper = mapper(Employee,
                                 employees_table,
                                 polymorphic_identity="employee")
        mapper(
            Manager,
            managers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="manager",
        )
        engineer_mapper = mapper(
            Engineer,
            engineers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="engineer",
        )
        mapper(
            Hacker,
            hackers_table,
            inherits=engineer_mapper,
            concrete=True,
            polymorphic_identity="hacker",
        )
        session = create_session()
        jdoe = Employee("Jdoe")
        tom = Manager("Tom", "knows how to manage things")
        jerry = Engineer("Jerry", "knows how to program")
        hacker = Hacker("Kurt", "Badass", "knows how to hack")
        session.add_all((jdoe, tom, jerry, hacker))
        session.flush()
        eq_(
            len(
                testing.db.execute(
                    session.query(Employee).with_polymorphic(
                        "*", pjoin,
                        pjoin.c.type).with_labels().statement).fetchall()),
            4,
        )
        eq_(session.query(Employee).get(jdoe.employee_id), jdoe)
        eq_(session.query(Engineer).get(jerry.employee_id), jerry)
        eq_(
            set([
                repr(x) for x in session.query(Employee).with_polymorphic(
                    "*", pjoin, pjoin.c.type)
            ]),
            set([
                "Employee Jdoe",
                "Engineer Jerry knows how to program",
                "Manager Tom knows how to manage things",
                "Hacker Kurt 'Badass' knows how to hack",
            ]),
        )
        eq_(
            set([repr(x) for x in session.query(Manager)]),
            set(["Manager Tom knows how to manage things"]),
        )
        eq_(
            set([
                repr(x) for x in session.query(Engineer).with_polymorphic(
                    "*", pjoin2, pjoin2.c.type)
            ]),
            set([
                "Engineer Jerry knows how to program",
                "Hacker Kurt 'Badass' knows how to hack",
            ]),
        )
        eq_(
            set([repr(x) for x in session.query(Hacker)]),
            set(["Hacker Kurt 'Badass' knows how to hack"]),
        )

        # test adaption of the column by wrapping the query in a
        # subquery

        eq_(
            len(
                testing.db.execute(
                    session.query(Engineer).with_polymorphic(
                        "*", pjoin2,
                        pjoin2.c.type).from_self().statement).fetchall()),
            2,
        )
        eq_(
            set([
                repr(x) for x in session.query(Engineer).with_polymorphic(
                    "*", pjoin2, pjoin2.c.type).from_self()
            ]),
            set([
                "Engineer Jerry knows how to program",
                "Hacker Kurt 'Badass' knows how to hack",
            ]),
        )
Exemple #10
0
    def test_multi_level_with_base(self):
        pjoin = polymorphic_union(
            {
                "employee": employees_table,
                "manager": managers_table,
                "engineer": engineers_table,
                "hacker": hackers_table,
            },
            "type",
            "pjoin",
        )
        pjoin2 = polymorphic_union(
            {
                "engineer": engineers_table,
                "hacker": hackers_table
            },
            "type",
            "pjoin2",
        )
        employee_mapper = mapper(
            Employee,
            employees_table,
            with_polymorphic=("*", pjoin),
            polymorphic_on=pjoin.c.type,
        )
        mapper(
            Manager,
            managers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="manager",
        )
        engineer_mapper = mapper(
            Engineer,
            engineers_table,
            with_polymorphic=("*", pjoin2),
            polymorphic_on=pjoin2.c.type,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="engineer",
        )
        mapper(
            Hacker,
            hackers_table,
            inherits=engineer_mapper,
            concrete=True,
            polymorphic_identity="hacker",
        )
        session = create_session()
        tom = Manager("Tom", "knows how to manage things")
        jerry = Engineer("Jerry", "knows how to program")
        hacker = Hacker("Kurt", "Badass", "knows how to hack")
        session.add_all((tom, jerry, hacker))
        session.flush()

        def go():
            eq_(jerry.name, "Jerry")
            eq_(hacker.nickname, "Badass")

        self.assert_sql_count(testing.db, go, 0)
        session.expunge_all()

        # check that we aren't getting a cartesian product in the raw
        # SQL. this requires that Engineer's polymorphic discriminator
        # is not rendered in the statement which is only against
        # Employee's "pjoin"

        assert (len(
            testing.db.execute(
                session.query(Employee).with_labels().statement).fetchall()) ==
                3)
        assert set([repr(x) for x in session.query(Employee)]) == set([
            "Engineer Jerry knows how to program",
            "Manager Tom knows how to manage things",
            "Hacker Kurt 'Badass' knows how to hack",
        ])
        assert set([repr(x) for x in session.query(Manager)
                    ]) == set(["Manager Tom knows how to manage things"])
        assert set([repr(x) for x in session.query(Engineer)]) == set([
            "Engineer Jerry knows how to program",
            "Hacker Kurt 'Badass' knows how to hack",
        ])
        assert set([repr(x) for x in session.query(Hacker)
                    ]) == set(["Hacker Kurt 'Badass' knows how to hack"])
Exemple #11
0
    def test_multi_level_no_base_w_hybrid(self):
        pjoin = polymorphic_union(
            {
                "manager": managers_table,
                "engineer": engineers_table,
                "hacker": hackers_table,
            },
            "type",
            "pjoin",
        )

        test_calls = mock.Mock()

        class ManagerWHybrid(Employee):
            def __init__(self, name, manager_data):
                self.name = name
                self.manager_data = manager_data

            @hybrid_property
            def engineer_info(self):
                test_calls.engineer_info_instance()
                return self.manager_data

            @engineer_info.expression
            def engineer_info(cls):
                test_calls.engineer_info_class()
                return cls.manager_data

        employee_mapper = mapper(Employee, pjoin, polymorphic_on=pjoin.c.type)
        mapper(
            ManagerWHybrid,
            managers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="manager",
        )
        mapper(
            Engineer,
            engineers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="engineer",
        )

        session = create_session()
        tom = ManagerWHybrid("Tom", "mgrdata")

        # mapping did not impact the engineer_info
        # hybrid in any way
        eq_(test_calls.mock_calls, [])

        eq_(tom.engineer_info, "mgrdata")
        eq_(test_calls.mock_calls, [mock.call.engineer_info_instance()])

        session.add(tom)
        session.flush()

        session.close()

        tom = (session.query(ManagerWHybrid).filter(
            ManagerWHybrid.engineer_info == "mgrdata").one())
        eq_(
            test_calls.mock_calls,
            [
                mock.call.engineer_info_instance(),
                mock.call.engineer_info_class(),
            ],
        )
        eq_(tom.engineer_info, "mgrdata")
Exemple #12
0
    def test_multi_level_no_base(self):
        pjoin = polymorphic_union(
            {
                "manager": managers_table,
                "engineer": engineers_table,
                "hacker": hackers_table,
            },
            "type",
            "pjoin",
        )
        pjoin2 = polymorphic_union(
            {
                "engineer": engineers_table,
                "hacker": hackers_table
            },
            "type",
            "pjoin2",
        )
        employee_mapper = mapper(Employee, pjoin, polymorphic_on=pjoin.c.type)
        mapper(
            Manager,
            managers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="manager",
        )
        engineer_mapper = mapper(
            Engineer,
            engineers_table,
            with_polymorphic=("*", pjoin2),
            polymorphic_on=pjoin2.c.type,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="engineer",
        )
        mapper(
            Hacker,
            hackers_table,
            inherits=engineer_mapper,
            concrete=True,
            polymorphic_identity="hacker",
        )
        session = create_session()
        tom = Manager("Tom", "knows how to manage things")

        assert_raises_message(
            AttributeError,
            "does not implement attribute .?'type' at the instance level.",
            setattr,
            tom,
            "type",
            "sometype",
        )

        jerry = Engineer("Jerry", "knows how to program")
        hacker = Hacker("Kurt", "Badass", "knows how to hack")

        assert_raises_message(
            AttributeError,
            "does not implement attribute .?'type' at the instance level.",
            setattr,
            hacker,
            "type",
            "sometype",
        )

        session.add_all((tom, jerry, hacker))
        session.flush()

        # ensure "readonly" on save logic didn't pollute the
        # expired_attributes collection

        assert ("nickname"
                not in attributes.instance_state(jerry).expired_attributes)
        assert ("name"
                not in attributes.instance_state(jerry).expired_attributes)
        assert ("name"
                not in attributes.instance_state(hacker).expired_attributes)
        assert ("nickname"
                not in attributes.instance_state(hacker).expired_attributes)

        def go():
            eq_(jerry.name, "Jerry")
            eq_(hacker.nickname, "Badass")

        self.assert_sql_count(testing.db, go, 0)
        session.expunge_all()
        assert (repr(
            session.query(Employee).filter(Employee.name == "Tom").one()) ==
                "Manager Tom knows how to manage things")
        assert (repr(
            session.query(Manager).filter(Manager.name == "Tom").one()) ==
                "Manager Tom knows how to manage things")
        assert set([repr(x) for x in session.query(Employee).all()]) == set([
            "Engineer Jerry knows how to program",
            "Manager Tom knows how to manage things",
            "Hacker Kurt 'Badass' knows how to hack",
        ])
        assert set([repr(x) for x in session.query(Manager).all()
                    ]) == set(["Manager Tom knows how to manage things"])
        assert set([repr(x) for x in session.query(Engineer).all()]) == set([
            "Engineer Jerry knows how to program",
            "Hacker Kurt 'Badass' knows how to hack",
        ])
        assert set([repr(x) for x in session.query(Hacker).all()
                    ]) == set(["Hacker Kurt 'Badass' knows how to hack"])
    def setup_mappers(cls):
        include_base = cls.include_base
        lazy_relationship = cls.lazy_relationship
        redefine_colprop = cls.redefine_colprop
        with_polymorphic = cls.with_polymorphic

        if with_polymorphic == "unions":
            if include_base:
                person_join = polymorphic_union(
                    {
                        "engineer": people.join(engineers),
                        "manager": people.join(managers),
                        "person": people.select(people.c.type == "person"),
                    },
                    None,
                    "pjoin",
                )
            else:
                person_join = polymorphic_union(
                    {
                        "engineer": people.join(engineers),
                        "manager": people.join(managers),
                    },
                    None,
                    "pjoin",
                )

            manager_join = people.join(managers).outerjoin(boss)
            person_with_polymorphic = ["*", person_join]
            manager_with_polymorphic = ["*", manager_join]
        elif with_polymorphic == "joins":
            person_join = (people.outerjoin(engineers).outerjoin(
                managers).outerjoin(boss))
            manager_join = people.join(managers).outerjoin(boss)
            person_with_polymorphic = ["*", person_join]
            manager_with_polymorphic = ["*", manager_join]
        elif with_polymorphic == "auto":
            person_with_polymorphic = "*"
            manager_with_polymorphic = "*"
        else:
            person_with_polymorphic = None
            manager_with_polymorphic = None

        if redefine_colprop:
            person_mapper = mapper(
                Person,
                people,
                with_polymorphic=person_with_polymorphic,
                polymorphic_on=people.c.type,
                polymorphic_identity="person",
                properties={"person_name": people.c.name},
            )
        else:
            person_mapper = mapper(
                Person,
                people,
                with_polymorphic=person_with_polymorphic,
                polymorphic_on=people.c.type,
                polymorphic_identity="person",
            )

        mapper(
            Engineer,
            engineers,
            inherits=person_mapper,
            polymorphic_identity="engineer",
        )
        mapper(
            Manager,
            managers,
            inherits=person_mapper,
            with_polymorphic=manager_with_polymorphic,
            polymorphic_identity="manager",
        )

        mapper(Boss, boss, inherits=Manager, polymorphic_identity="boss")

        mapper(
            Company,
            companies,
            properties={
                "employees":
                relationship(
                    Person,
                    lazy=lazy_relationship,
                    cascade="all, delete-orphan",
                    backref="company",
                    order_by=people.c.person_id,
                )
            },
        )
    def test_insert_order(self):
        """test that classes of multiple types mix up mapper inserts
        so that insert order of individual tables is maintained"""

        person_join = polymorphic_union(
            {
                "engineer": people.join(engineers),
                "manager": people.join(managers),
                "person": people.select(people.c.type == "person"),
            },
            None,
            "pjoin",
        )

        person_mapper = mapper(
            Person,
            people,
            with_polymorphic=("*", person_join),
            polymorphic_on=person_join.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,
                             backref="company",
                             order_by=person_join.c.person_id)
            },
        )

        session = create_session()
        c = Company(name="company1")
        c.employees.append(
            Manager(
                status="AAB",
                manager_name="manager1",
                name="pointy haired boss",
            ))
        c.employees.append(
            Engineer(
                status="BBA",
                engineer_name="engineer1",
                primary_language="java",
                name="dilbert",
            ))
        c.employees.append(Person(status="HHH", name="joesmith"))
        c.employees.append(
            Engineer(
                status="CGG",
                engineer_name="engineer2",
                primary_language="python",
                name="wally",
            ))
        c.employees.append(
            Manager(status="ABA", manager_name="manager2", name="jsmith"))
        session.add(c)
        session.flush()
        session.expunge_all()
        eq_(session.query(Company).get(c.company_id), c)