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()
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()
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)
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" }]), }, )
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"], )
class A(cls.DeclarativeBasic): __tablename__ = "a" id = Column(Integer, primary_key=True) b_id = Column(ForeignKey("b.id")) b = relationship("B")