def test_nonpoly_oftype_subclass(self):
        Company = _poly_fixtures.Company
        Person = _poly_fixtures.Person
        Engineer = _poly_fixtures.Engineer
        emapper = inspect(Engineer)
        cmapper = inspect(Company)
        pmapper = inspect(Person)

        p1 = PathRegistry.coerce(
            (
                cmapper,
                cmapper.attrs.employees,
                emapper,
                emapper.attrs.paperwork,
            )
        )

        eq_(
            p1.path,
            (
                cmapper,
                cmapper.attrs.employees,
                pmapper,
                pmapper.attrs.paperwork,
            ),
        )
        eq_(
            p1.natural_path,
            (
                cmapper,
                cmapper.attrs.employees,
                pmapper,
                pmapper.attrs.paperwork,
            ),
        )
    def test_length(self):
        umapper = inspect(self.classes.User)
        amapper = inspect(self.classes.Address)
        pneg1 = PathRegistry.coerce(())
        p0 = PathRegistry.coerce((umapper,))
        p1 = PathRegistry.coerce((umapper, umapper.attrs.addresses))
        p2 = PathRegistry.coerce((umapper, umapper.attrs.addresses, amapper))
        p3 = PathRegistry.coerce(
            (
                umapper,
                umapper.attrs.addresses,
                amapper,
                amapper.attrs.email_address,
            )
        )

        eq_(len(pneg1), 0)
        eq_(len(p0), 1)
        eq_(len(p1), 2)
        eq_(len(p2), 3)
        eq_(len(p3), 4)
        eq_(pneg1.length, 0)
        eq_(p0.length, 1)
        eq_(p1.length, 2)
        eq_(p2.length, 3)
        eq_(p3.length, 4)
    def test_serialize_context_dict(self):
        reg = util.OrderedDict()
        umapper = inspect(self.classes.User)
        amapper = inspect(self.classes.Address)

        p1 = PathRegistry.coerce((umapper, umapper.attrs.addresses))
        p2 = PathRegistry.coerce((umapper, umapper.attrs.addresses, amapper))
        p3 = PathRegistry.coerce((amapper, amapper.attrs.email_address))

        p1.set(reg, "p1key", "p1value")
        p2.set(reg, "p2key", "p2value")
        p3.set(reg, "p3key", "p3value")
        eq_(
            reg,
            {
                ("p1key", p1.path): "p1value",
                ("p2key", p2.path): "p2value",
                ("p3key", p3.path): "p3value",
            },
        )

        serialized = PathRegistry.serialize_context_dict(
            reg, ("p1key", "p2key")
        )
        eq_(
            serialized,
            [
                (("p1key", p1.serialize()), "p1value"),
                (("p2key", p2.serialize()), "p2value"),
            ],
        )
    def test_plain_aliased_compound(self):
        Company = _poly_fixtures.Company
        Person = _poly_fixtures.Person
        Engineer = _poly_fixtures.Engineer
        cmapper = inspect(Company)
        emapper = inspect(Engineer)

        c_alias = aliased(Company)
        p_alias = aliased(Person)

        c_alias = inspect(c_alias)
        p_alias = inspect(p_alias)

        p1 = PathRegistry.coerce(
            (c_alias, cmapper.attrs.employees, p_alias, emapper.attrs.machines)
        )
        # plain AliasedClass - the path keeps that AliasedClass directly
        # as is in the path
        eq_(
            p1.path,
            (
                c_alias,
                cmapper.attrs.employees,
                p_alias,
                emapper.attrs.machines,
            ),
        )
Beispiel #5
0
 def test_info(self):
     A = self._fixture()
     inspect(A).all_orm_descriptors.value.info["some key"] = "some value"
     eq_(
         inspect(A).all_orm_descriptors.value.info,
         {"some key": "some value"},
     )
    def test_eq(self):
        umapper = inspect(self.classes.User)
        amapper = inspect(self.classes.Address)
        u_alias = inspect(aliased(self.classes.User))
        p1 = PathRegistry.coerce((umapper, umapper.attrs.addresses))
        p2 = PathRegistry.coerce((umapper, umapper.attrs.addresses))
        p3 = PathRegistry.coerce((umapper, umapper.attrs.name))
        p4 = PathRegistry.coerce((u_alias, umapper.attrs.addresses))
        p5 = PathRegistry.coerce((umapper, umapper.attrs.addresses, amapper))
        p6 = PathRegistry.coerce(
            (amapper, amapper.attrs.user, umapper, umapper.attrs.addresses)
        )
        p7 = PathRegistry.coerce(
            (
                amapper,
                amapper.attrs.user,
                umapper,
                umapper.attrs.addresses,
                amapper,
                amapper.attrs.email_address,
            )
        )

        is_(p1 == p2, True)
        is_(p1 == p3, False)
        is_(p1 == p4, False)
        is_(p1 == p5, False)
        is_(p6 == p7, False)
        is_(p6 == p7.parent.parent, True)

        is_(p1 != p2, False)
        is_(p1 != p3, True)
        is_(p1 != p4, True)
        is_(p1 != p5, True)
    def test_attrs_props_prop_added_after_configure(self):
        class Thing(InspectionAttr):
            pass

        class AnonClass(object):
            __foo__ = "bar"
            __bat__ = Thing()

        from sqlalchemy_1_3.orm import mapper, column_property
        from sqlalchemy_1_3.ext.hybrid import hybrid_property

        m = mapper(AnonClass, self.tables.users)

        eq_(set(inspect(AnonClass).attrs.keys()), set(["id", "name"]))
        eq_(
            set(inspect(AnonClass).all_orm_descriptors.keys()),
            set(["id", "name"]),
        )

        m.add_property("q", column_property(self.tables.users.c.name))

        def desc(self):
            return self.name

        AnonClass.foob = hybrid_property(desc)

        eq_(set(inspect(AnonClass).attrs.keys()), set(["id", "name", "q"]))
        eq_(
            set(inspect(AnonClass).all_orm_descriptors.keys()),
            set(["id", "name", "q", "foob"]),
        )
    def test_deseralize(self):
        User = self.classes.User
        Address = self.classes.Address
        umapper = inspect(self.classes.User)
        amapper = inspect(self.classes.Address)

        p1 = PathRegistry.coerce(
            (
                umapper,
                umapper.attrs.addresses,
                amapper,
                amapper.attrs.email_address,
            )
        )
        p2 = PathRegistry.coerce((umapper, umapper.attrs.addresses, amapper))
        p3 = PathRegistry.coerce((umapper, umapper.attrs.addresses))

        eq_(
            PathRegistry.deserialize(
                [(User, "addresses"), (Address, "email_address")]
            ),
            p1,
        )
        eq_(
            PathRegistry.deserialize([(User, "addresses"), (Address, None)]),
            p2,
        )
        eq_(PathRegistry.deserialize([(User, "addresses")]), p3)
 def test_aliased_class(self):
     Address = self.classes.Address
     ualias = aliased(Address)
     insp = inspect(ualias)
     is_(insp.mapper, inspect(Address))
     is_(insp.selectable, ualias._aliased_insp.selectable)
     assert not insp.is_selectable
     assert insp.is_aliased_class
    def test_with_poly_sub(self):
        Company = _poly_fixtures.Company
        Person = _poly_fixtures.Person
        Engineer = _poly_fixtures.Engineer
        emapper = inspect(Engineer)
        cmapper = inspect(Company)

        p_poly = with_polymorphic(Person, [Engineer])
        e_poly_insp = inspect(p_poly.Engineer)  # noqa - used by comment below
        p_poly_insp = inspect(p_poly)

        p1 = PathRegistry.coerce((p_poly_insp, emapper.attrs.machines))

        # changes as of #5082: when a with_polymorphic is in the middle
        # of a path, the natural path makes sure it uses the base mappers,
        # however when it's at the root, the with_polymorphic stays in
        # the natural path

        # this behavior is the same as pre #5082, it was temporarily changed
        # but this proved to be incorrect.   The path starts on a
        # with_polymorphic(), so a Query will "naturally" construct a path
        # that comes from that wp.
        eq_(p1.path, (e_poly_insp, emapper.attrs.machines))
        eq_(p1.natural_path, (e_poly_insp, emapper.attrs.machines))

        # this behavior is new as of the final version of #5082.
        # the path starts on a normal entity and has a with_polymorphic
        # in the middle, for this to match what Query will generate it needs
        # to use the non aliased mappers in the natural path.
        p2 = PathRegistry.coerce(
            (
                cmapper,
                cmapper.attrs.employees,
                p_poly_insp,
                emapper.attrs.machines,
            )
        )
        eq_(
            p2.path,
            (
                cmapper,
                cmapper.attrs.employees,
                e_poly_insp,
                emapper.attrs.machines,
            ),
        )
        eq_(
            p2.natural_path,
            (
                cmapper,
                cmapper.attrs.employees,
                emapper,
                emapper.attrs.machines,
            ),
        )
    def test_is_instance(self):
        User = self.classes.User
        u1 = User(name="ed")
        insp = inspect(u1)
        assert insp.is_instance

        insp = inspect(User)
        assert not insp.is_instance

        insp = inspect(aliased(User))
        assert not insp.is_instance
    def test_plain(self):
        Person = _poly_fixtures.Person
        Engineer = _poly_fixtures.Engineer
        pmapper = inspect(Person)
        emapper = inspect(Engineer)

        p1 = PathRegistry.coerce((pmapper, emapper.attrs.machines))

        # given a mapper and an attribute on a subclass,
        # the path converts what you get to be against that subclass
        eq_(p1.path, (emapper, emapper.attrs.machines))
    def test_path(self):
        umapper = inspect(self.classes.User)
        amapper = inspect(self.classes.Address)

        p1 = PathRegistry.coerce((umapper, umapper.attrs.addresses))
        p2 = PathRegistry.coerce((umapper, umapper.attrs.addresses, amapper))
        p3 = PathRegistry.coerce((amapper, amapper.attrs.email_address))

        eq_(p1.path, (umapper, umapper.attrs.addresses))
        eq_(p2.path, (umapper, umapper.attrs.addresses, amapper))
        eq_(p3.path, (amapper, amapper.attrs.email_address))
    def test_plain_aliased(self):
        Person = _poly_fixtures.Person
        Engineer = _poly_fixtures.Engineer
        emapper = inspect(Engineer)

        p_alias = aliased(Person)
        p_alias = inspect(p_alias)

        p1 = PathRegistry.coerce((p_alias, emapper.attrs.machines))
        # plain AliasedClass - the path keeps that AliasedClass directly
        # as is in the path
        eq_(p1.path, (p_alias, emapper.attrs.machines))
 def test_slice(self):
     umapper = inspect(self.classes.User)
     amapper = inspect(self.classes.Address)
     path = PathRegistry.coerce(
         (
             umapper,
             umapper.attrs.addresses,
             amapper,
             amapper.attrs.email_address,
         )
     )
     eq_(path[1:3], (umapper.attrs.addresses, amapper))
 def test_indexed_key(self):
     umapper = inspect(self.classes.User)
     amapper = inspect(self.classes.Address)
     path = PathRegistry.coerce(
         (
             umapper,
             umapper.attrs.addresses,
             amapper,
             amapper.attrs.email_address,
         )
     )
     eq_(path[1], umapper.attrs.addresses)
     eq_(path[3], amapper.attrs.email_address)
 def test_indexed_entity(self):
     umapper = inspect(self.classes.User)
     amapper = inspect(self.classes.Address)
     path = PathRegistry.coerce(
         (
             umapper,
             umapper.attrs.addresses,
             amapper,
             amapper.attrs.email_address,
         )
     )
     is_(path[0], umapper)
     is_(path[2], amapper)
    def test_with_poly_use_mapper(self):
        Person = _poly_fixtures.Person
        Engineer = _poly_fixtures.Engineer
        emapper = inspect(Engineer)

        p_poly = with_polymorphic(Person, [Engineer], _use_mapper_path=True)
        p_poly = inspect(p_poly)

        p1 = PathRegistry.coerce((p_poly, emapper.attrs.machines))

        # polymorphic AliasedClass with the "use_mapper_path" flag -
        # the AliasedClass acts just like the base mapper
        eq_(p1.path, (emapper, emapper.attrs.machines))
Beispiel #19
0
    def test_state_info_pickle(self):
        users = self.tables.users
        mapper(User, users)

        u1 = User(id=1, name="ed")

        sa.inspect(u1).info["some_key"] = "value"

        state_dict = sa.inspect(u1).__getstate__()

        state = sa_state.InstanceState.__new__(sa_state.InstanceState)
        state.__setstate__(state_dict)

        u2 = state.obj()
        eq_(sa.inspect(u2).info["some_key"], "value")
    def test_with_poly_base_one(self):
        Person = _poly_fixtures.Person
        Engineer = _poly_fixtures.Engineer
        pmapper = inspect(Person)
        emapper = inspect(Engineer)

        p_poly = with_polymorphic(Person, [Engineer])
        p_poly = inspect(p_poly)

        # "name" is actually on Person, not Engineer
        p1 = PathRegistry.coerce((p_poly, emapper.attrs.name))

        # polymorphic AliasedClass - because "name" is on Person,
        # we get Person, not Engineer
        eq_(p1.path, (p_poly, pmapper.attrs.name))
    def test_insp_aliased_column_prop(self):
        User = self.classes.User
        ua = aliased(User)
        prop = inspect(ua.name)
        is_(prop, ua.name)

        is_(prop.property.parent.mapper, class_mapper(User))
        assert not hasattr(prop.property, "mapper")
        is_(prop.parent.entity, ua)
        is_(prop.parent.class_, User)
        is_(prop._parentmapper, class_mapper(User))

        assert not hasattr(prop, "mapper")

        is_(prop._parententity, inspect(ua))
    def test_insp_aliased_relationship_prop(self):
        User = self.classes.User
        Address = self.classes.Address
        ua = aliased(User)
        prop = inspect(ua.addresses)
        is_(prop, ua.addresses)

        is_(prop.property.parent.mapper, class_mapper(User))
        is_(prop.property.mapper, class_mapper(Address))
        is_(prop.parent.entity, ua)
        is_(prop.parent.class_, User)
        is_(prop._parentmapper, class_mapper(User))
        is_(prop.mapper, class_mapper(Address))

        is_(prop._parententity, inspect(ua))
Beispiel #23
0
    def test_no_pk(self):
        metadata = self.metadata

        Table(
            "sometable",
            metadata,
            Column("id_a", Unicode(255)),
            Column("id_b", Unicode(255)),
            Index("pk_idx_1", "id_a", "id_b", unique=True),
            Index("pk_idx_2", "id_b", "id_a", unique=True),
        )
        metadata.create_all()

        insp = inspect(testing.db)
        eq_(
            insp.get_indexes("sometable"),
            [
                {
                    "name": "pk_idx_1",
                    "column_names": ["id_a", "id_b"],
                    "dialect_options": {},
                    "unique": True,
                },
                {
                    "name": "pk_idx_2",
                    "column_names": ["id_b", "id_a"],
                    "dialect_options": {},
                    "unique": True,
                },
            ],
        )
Beispiel #24
0
    def test_select(self):
        t = Table("t", MetaData(), Column("x", Integer))
        s = t.select()

        is_(inspect(s), s)
        assert s.is_selectable
        is_(s.selectable, s)
Beispiel #25
0
    def test_reflect_table_comment(self):
        local_parent = Table(
            "parent",
            self.metadata,
            Column("q", Integer),
            comment="my local comment",
        )

        local_parent.create(testing.db)

        insp = inspect(testing.db)
        eq_(
            insp.get_table_comment("parent",
                                   schema=testing.config.test_schema),
            {"text": "my table comment"},
        )
        eq_(
            insp.get_table_comment("parent", ),
            {"text": "my local comment"},
        )
        eq_(
            insp.get_table_comment(
                "parent", schema=testing.db.dialect.default_schema_name),
            {"text": "my local comment"},
        )
    def test_get_includes_getclause(self):
        # test issue #3597
        User = self.classes.User

        bq = self.bakery(lambda s: s.query(User))

        for i in range(5):
            sess = Session()
            u1 = bq(sess).get(7)
            eq_(u1.name, "jack")
            sess.close()

        eq_(len(bq._bakery), 2)

        # simulate race where mapper._get_clause
        # may be generated more than once
        from sqlalchemy_1_3 import inspect

        del inspect(User).__dict__["_get_clause"]

        for i in range(5):
            sess = Session()
            u1 = bq(sess).get(7)
            eq_(u1.name, "jack")
            sess.close()
        eq_(len(bq._bakery), 4)
Beispiel #27
0
    def test_info_from_hybrid(self):
        A = self._fixture()
        A._value.info["foo"] = "bar"
        A.value.info["bar"] = "hoho"

        insp = inspect(A)
        is_(insp.all_orm_descriptors["value"].info, A.value.info)
Beispiel #28
0
    def test_view_reflection(self):
        Table("x", self.metadata, Column("a", Integer),
              Column("b", String(50)))
        self.metadata.create_all()

        with testing.db.connect() as conn:
            conn.execute("CREATE VIEW v1 AS SELECT * FROM x")
            conn.execute("CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM x")
            conn.execute(
                "CREATE ALGORITHM=UNDEFINED VIEW v3 AS SELECT * FROM x")
            conn.execute(
                "CREATE DEFINER=CURRENT_USER VIEW v4 AS SELECT * FROM x")

        @event.listens_for(self.metadata, "before_drop")
        def cleanup(*arg, **kw):
            with testing.db.connect() as conn:
                for v in ["v1", "v2", "v3", "v4"]:
                    conn.execute("DROP VIEW %s" % v)

        insp = inspect(testing.db)
        for v in ["v1", "v2", "v3", "v4"]:
            eq_(
                [(col["name"], col["type"].__class__)
                 for col in insp.get_columns(v)],
                [("a", mysql.INTEGER), ("b", mysql.VARCHAR)],
            )
Beispiel #29
0
    def test_reflection_with_unique_constraint(self):
        insp = inspect(testing.db)

        meta = self.metadata
        uc_table = Table(
            "mysql_uc",
            meta,
            Column("a", String(10)),
            UniqueConstraint("a", name="uc_a"),
        )

        uc_table.create()

        # MySQL converts unique constraints into unique indexes.
        # separately we get both
        indexes = dict((i["name"], i) for i in insp.get_indexes("mysql_uc"))
        constraints = set(i["name"]
                          for i in insp.get_unique_constraints("mysql_uc"))

        self.assert_("uc_a" in indexes)
        self.assert_(indexes["uc_a"]["unique"])
        self.assert_("uc_a" in constraints)

        # reflection here favors the unique index, as that's the
        # more "official" MySQL construct
        reflected = Table("mysql_uc", MetaData(testing.db), autoload=True)

        indexes = dict((i.name, i) for i in reflected.indexes)
        constraints = set(uc.name for uc in reflected.constraints)

        self.assert_("uc_a" in indexes)
        self.assert_(indexes["uc_a"].unique)
        self.assert_("uc_a" not in constraints)
 def test_addition(self):
     umapper = inspect(self.classes.User)
     amapper = inspect(self.classes.Address)
     p1 = PathRegistry.coerce((umapper, umapper.attrs.addresses))
     p2 = PathRegistry.coerce((amapper, amapper.attrs.email_address))
     eq_(
         p1 + p2,
         PathRegistry.coerce(
             (
                 umapper,
                 umapper.attrs.addresses,
                 amapper,
                 amapper.attrs.email_address,
             )
         ),
     )