예제 #1
0
    def test_session(self):
        metadata = MetaData(self.engine)

        table1 = Table(
            "mytable",
            metadata,
            Column(
                "col1",
                Integer,
                primary_key=True,
                test_needs_autoincrement=True,
            ),
            Column("col2", String(30)),
        )

        table2 = Table(
            "mytable2",
            metadata,
            Column(
                "col1",
                Integer,
                primary_key=True,
                test_needs_autoincrement=True,
            ),
            Column("col2", String(30)),
            Column("col3", Integer, ForeignKey("mytable.col1")),
        )

        metadata.create_all()

        m1 = mapper(
            A,
            table1,
            properties={
                "bs":
                relationship(B, cascade="all, delete", order_by=table2.c.col1)
            },
        )
        m2 = mapper(B, table2)

        @profile_memory()
        def go():
            sess = create_session()
            a1 = A(col2="a1")
            a2 = A(col2="a2")
            a3 = A(col2="a3")
            a1.bs.append(B(col2="b1"))
            a1.bs.append(B(col2="b2"))
            a3.bs.append(B(col2="b3"))
            for x in [a1, a2, a3]:
                sess.add(x)
            sess.flush()
            sess.expunge_all()

            alist = sess.query(A).order_by(A.col1).all()
            eq_(
                [
                    A(col2="a1", bs=[B(col2="b1"), B(col2="b2")]),
                    A(col2="a2", bs=[]),
                    A(col2="a3", bs=[B(col2="b3")]),
                ],
                alist,
            )

            for a in alist:
                sess.delete(a)
            sess.flush()

        go()

        metadata.drop_all()
        del m1, m2
        assert_no_mappers()
예제 #2
0
    def test_orm_many_engines(self):
        metadata = MetaData(self.engine)

        table1 = Table(
            "mytable",
            metadata,
            Column(
                "col1",
                Integer,
                primary_key=True,
                test_needs_autoincrement=True,
            ),
            Column("col2", String(30)),
        )

        table2 = Table(
            "mytable2",
            metadata,
            Column(
                "col1",
                Integer,
                primary_key=True,
                test_needs_autoincrement=True,
            ),
            Column("col2", String(30)),
            Column("col3", Integer, ForeignKey("mytable.col1")),
        )

        metadata.create_all()

        m1 = mapper(
            A,
            table1,
            properties={
                "bs":
                relationship(B, cascade="all, delete", order_by=table2.c.col1)
            },
            _compiled_cache_size=50,
        )
        m2 = mapper(B, table2, _compiled_cache_size=50)

        @profile_memory()
        def go():
            engine = engines.testing_engine(
                options={
                    "logging_name": "FOO",
                    "pool_logging_name": "BAR",
                    "use_reaper": False,
                })
            sess = create_session(bind=engine)

            a1 = A(col2="a1")
            a2 = A(col2="a2")
            a3 = A(col2="a3")
            a1.bs.append(B(col2="b1"))
            a1.bs.append(B(col2="b2"))
            a3.bs.append(B(col2="b3"))
            for x in [a1, a2, a3]:
                sess.add(x)
            sess.flush()
            sess.expunge_all()

            alist = sess.query(A).order_by(A.col1).all()
            eq_(
                [
                    A(col2="a1", bs=[B(col2="b1"), B(col2="b2")]),
                    A(col2="a2", bs=[]),
                    A(col2="a3", bs=[B(col2="b3")]),
                ],
                alist,
            )

            for a in alist:
                sess.delete(a)
            sess.flush()
            sess.close()
            engine.dispose()

        go()

        metadata.drop_all()
        del m1, m2
        assert_no_mappers()
예제 #3
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)
예제 #4
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)
    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)
    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_five(self):
        """tests the late compilation of mappers"""

        mapper(
            SpecLine,
            specification_table,
            properties=dict(
                leader=relationship(
                    Assembly,
                    lazy="joined",
                    uselist=False,
                    foreign_keys=[specification_table.c.leader_id],
                    primaryjoin=specification_table.c.leader_id ==
                    products_table.c.product_id,
                    backref=backref("specification"),
                ),
                follower=relationship(
                    Product,
                    lazy="joined",
                    uselist=False,
                    foreign_keys=[specification_table.c.follower_id],
                    primaryjoin=specification_table.c.follower_id ==
                    products_table.c.product_id,
                ),
                quantity=specification_table.c.quantity,
            ),
        )

        mapper(
            Product,
            products_table,
            polymorphic_on=products_table.c.product_type,
            polymorphic_identity="product",
            properties={
                "documents":
                relationship(
                    Document,
                    lazy="select",
                    backref="product",
                    cascade="all, delete-orphan",
                )
            },
        )

        mapper(Detail, inherits=Product, polymorphic_identity="detail")

        mapper(
            Document,
            documents_table,
            polymorphic_on=documents_table.c.document_type,
            polymorphic_identity="document",
            properties=dict(
                name=documents_table.c.name,
                data=deferred(documents_table.c.data),
            ),
        )

        mapper(
            RasterDocument,
            inherits=Document,
            polymorphic_identity="raster_document",
        )

        mapper(Assembly, inherits=Product, polymorphic_identity="assembly")

        session = create_session()

        a1 = Assembly(name="a1")
        a1.specification.append(SpecLine(follower=Detail(name="d1")))
        a1.documents.append(Document("doc1"))
        a1.documents.append(RasterDocument("doc2"))
        session.add(a1)
        orig = repr(a1)
        session.flush()
        session.expunge_all()

        a1 = session.query(Product).filter_by(name="a1").one()
        new = repr(a1)
        print(orig)
        print(new)
        assert (orig == new == "<Assembly a1> specification="
                "[<SpecLine 1.0 <Detail d1>>] documents=[<Document doc1>, "
                "<RasterDocument doc2>]")
    def test_bidirectional(self):
        place_input, transition, Transition, Place, place, place_output = (
            self.tables.place_input,
            self.tables.transition,
            self.classes.Transition,
            self.classes.Place,
            self.tables.place,
            self.tables.place_output,
        )

        mapper(Place, place)
        mapper(
            Transition,
            transition,
            properties=dict(
                inputs=relationship(
                    Place,
                    place_output,
                    backref=backref("inputs",
                                    order_by=transition.c.transition_id),
                    order_by=Place.place_id,
                ),
                outputs=relationship(
                    Place,
                    place_input,
                    backref=backref("outputs",
                                    order_by=transition.c.transition_id),
                    order_by=Place.place_id,
                ),
            ),
        )

        t1 = Transition("transition1")
        t2 = Transition("transition2")
        t3 = Transition("transition3")
        p1 = Place("place1")
        p2 = Place("place2")
        p3 = Place("place3")

        sess = Session()
        sess.add_all([p3, p1, t1, t2, p2, t3])

        t1.inputs.append(p1)
        t1.inputs.append(p2)
        t1.outputs.append(p3)
        t2.inputs.append(p1)
        p2.inputs.append(t2)
        p3.inputs.append(t2)
        p1.outputs.append(t1)
        sess.commit()

        self.assert_result(
            [t1],
            Transition,
            {"outputs": (Place, [{
                "name": "place3"
            }, {
                "name": "place1"
            }])},
        )
        self.assert_result(
            [p2],
            Place,
            {
                "inputs": (
                    Transition,
                    [{
                        "name": "transition1"
                    }, {
                        "name": "transition2"
                    }],
                )
            },
        )
    def test_joinedload_on_double(self):
        """test that a mapper can have two eager relationships to the same table, via
        two different association tables.  aliases are required."""

        (
            place_input,
            transition,
            Transition,
            PlaceThingy,
            place,
            place_thingy,
            Place,
            place_output,
        ) = (
            self.tables.place_input,
            self.tables.transition,
            self.classes.Transition,
            self.classes.PlaceThingy,
            self.tables.place,
            self.tables.place_thingy,
            self.classes.Place,
            self.tables.place_output,
        )

        mapper(PlaceThingy, place_thingy)
        mapper(
            Place,
            place,
            properties={"thingies": relationship(PlaceThingy, lazy="joined")},
        )

        mapper(
            Transition,
            transition,
            properties=dict(
                inputs=relationship(Place, place_output, lazy="joined"),
                outputs=relationship(Place, place_input, lazy="joined"),
            ),
        )

        tran = Transition("transition1")
        tran.inputs.append(Place("place1"))
        tran.outputs.append(Place("place2"))
        tran.outputs.append(Place("place3"))
        sess = Session()
        sess.add(tran)
        sess.commit()

        r = sess.query(Transition).all()
        self.assert_unordered_result(
            r,
            Transition,
            {
                "name": "transition1",
                "inputs": (Place, [{
                    "name": "place1"
                }]),
                "outputs": (Place, [{
                    "name": "place2"
                }, {
                    "name": "place3"
                }]),
            },
        )
예제 #10
0
    def test_extension_types(self):
        from sqlalchemy_1_3.ext.associationproxy import (
            association_proxy,
            ASSOCIATION_PROXY,
        )
        from sqlalchemy_1_3.ext.hybrid import (
            hybrid_property,
            hybrid_method,
            HYBRID_PROPERTY,
            HYBRID_METHOD,
        )
        from sqlalchemy_1_3 import Table, MetaData, Integer, Column
        from sqlalchemy_1_3.orm import mapper
        from sqlalchemy_1_3.orm.interfaces import NOT_EXTENSION

        class SomeClass(self.classes.User):
            some_assoc = association_proxy("addresses", "email_address")

            @hybrid_property
            def upper_name(self):
                raise NotImplementedError()

            @hybrid_method
            def conv(self, fn):
                raise NotImplementedError()

        class Address(self.classes.Address):
            pass

        class SomeSubClass(SomeClass):
            @hybrid_property
            def upper_name(self):
                raise NotImplementedError()

            @hybrid_property
            def foo(self):
                raise NotImplementedError()

        m = MetaData()
        t = Table("sometable", m, Column("id", Integer, primary_key=True))
        ta = Table(
            "address_t",
            m,
            Column("id", Integer, primary_key=True),
            Column("s_id", ForeignKey("sometable.id")),
        )
        mapper(SomeClass, t, properties={"addresses": relationship(Address)})
        mapper(Address, ta)
        mapper(SomeSubClass, inherits=SomeClass)

        insp = inspect(SomeSubClass)
        eq_(
            dict((k, v.extension_type)
                 for k, v in list(insp.all_orm_descriptors.items())),
            {
                "id": NOT_EXTENSION,
                "name": NOT_EXTENSION,
                "name_syn": NOT_EXTENSION,
                "addresses": NOT_EXTENSION,
                "orders": NOT_EXTENSION,
                "upper_name": HYBRID_PROPERTY,
                "foo": HYBRID_PROPERTY,
                "conv": HYBRID_METHOD,
                "some_assoc": ASSOCIATION_PROXY,
            },
        )
        is_(
            insp.all_orm_descriptors.upper_name,
            SomeSubClass.__dict__["upper_name"],
        )
        is_(insp.all_orm_descriptors.some_assoc, SomeClass.some_assoc.parent)
        is_(
            inspect(SomeClass).all_orm_descriptors.upper_name,
            SomeClass.__dict__["upper_name"],
        )
예제 #11
0
        class A(cls.DeclarativeBasic):
            __tablename__ = "a"

            id = Column(Integer, primary_key=True)
            b_id = Column(ForeignKey("b.id"))
            b = relationship("B")