def test_noload_append(self): # test that a load of User.addresses is not emitted # when flushing an append User, Address = self._user_address_fixture() sess = Session() u1 = User(name="jack", addresses=[Address(email_address="a1")]) sess.add(u1) sess.commit() u1_id = u1.id sess.expire_all() u1.addresses.append(Address(email_address="a2")) self.assert_sql_execution( testing.db, sess.flush, CompiledSQL( "SELECT users.id AS users_id, users.name AS users_name " "FROM users WHERE users.id = :param_1", lambda ctx: [{ "param_1": u1_id }], ), CompiledSQL( "INSERT INTO addresses (user_id, email_address) " "VALUES (:user_id, :email_address)", lambda ctx: [{ "email_address": "a2", "user_id": u1_id }], ), )
def test_pending_combines_with_flushed(self): """test the combination of unflushed pending + lazy loaded from DB.""" Item, Keyword = (self.classes.Item, self.classes.Keyword) session = Session(testing.db, autoflush=False) k1 = Keyword(name="k1") k2 = Keyword(name="k2") i1 = Item(description="i1", keywords=[k1]) session.add(i1) session.add(k2) session.commit() k2.items.append(i1) # the pending # list is still here. eq_( set( attributes.instance_state( i1)._pending_mutations["keywords"].added_items), set([k2]), ) # because autoflush is off, k2 is still # coming in from pending eq_(i1.keywords, [k1, k2]) # prove it didn't flush eq_(session.scalar("select count(*) from item_keywords"), 1) # the pending collection was removed assert ("keywords" not in attributes.instance_state(i1)._pending_mutations)
def test_cast_type(self): Json = self.classes.Json s = Session(testing.db) j = Json(json={"field": 10}) s.add(j) s.commit() jq = s.query(Json).filter(Json.int_field == 10).one() eq_(j.id, jq.id) jq = s.query(Json).filter(Json.text_field == "10").one() eq_(j.id, jq.id) jq = s.query(Json).filter(Json.json_field.astext == "10").one() eq_(j.id, jq.id) jq = s.query(Json).filter(Json.text_field == "wrong").first() is_(jq, None) j.json = {"field": True} s.commit() jq = s.query(Json).filter(Json.text_field == "true").one() eq_(j.id, jq.id)
def test_collection(self): users, addresses, Address = ( self.tables.users, self.tables.addresses, self.classes.Address, ) canary = Mock() class User(fixtures.ComparableEntity): @validates("addresses") def validate_address(self, key, ad): canary(key, ad) assert "@" in ad.email_address return ad mapper(User, users, properties={"addresses": relationship(Address)}) mapper(Address, addresses) sess = Session() u1 = User(name="edward") a0 = Address(email_address="noemail") assert_raises(AssertionError, u1.addresses.append, a0) a1 = Address(id=15, email_address="*****@*****.**") u1.addresses.append(a1) eq_(canary.mock_calls, [call("addresses", a0), call("addresses", a1)]) sess.add(u1) sess.commit() eq_( sess.query(User).filter_by(name="edward").one(), User( name="edward", addresses=[Address(email_address="*****@*****.**")] ), )
def test_scalar(self): users = self.tables.users canary = Mock() class User(fixtures.ComparableEntity): @validates("name") def validate_name(self, key, name): canary(key, name) ne_(name, "fred") return name + " modified" mapper(User, users) sess = Session() u1 = User(name="ed") eq_(u1.name, "ed modified") assert_raises(AssertionError, setattr, u1, "name", "fred") eq_(u1.name, "ed modified") eq_(canary.mock_calls, [call("name", "ed"), call("name", "fred")]) sess.add(u1) sess.commit() eq_( sess.query(User).filter_by(name="ed modified").one(), User(name="ed"), )
def test_optimized_get(self): from sqlalchemy_1_3.ext.declarative import declarative_base Base = declarative_base(metadata=self.metadata) class Employee(Base): __tablename__ = "employee" id = Column(Integer, primary_key=True, test_needs_autoincrement=True) type = Column(String(10)) __mapper_args__ = {"polymorphic_on": type} class Engineer(Employee): __tablename__ = " engineer" id = Column(ForeignKey("employee.id"), primary_key=True) engineer_name = Column(String(50)) __mapper_args__ = {"polymorphic_identity": "engineer"} Base.metadata.create_all(testing.db) s = Session(testing.db) s.add(Engineer(engineer_name="wally")) s.commit() s.close() @assert_cycles() def go(): e1 = s.query(Employee).first() e1.engineer_name go()
def test_11_pickle(self): users = self.tables.users mapper(User, users) sess = Session() u1 = User(id=1, name="ed") sess.add(u1) sess.commit() sess.close() manager = instrumentation._SerializeManager.__new__( instrumentation._SerializeManager ) manager.class_ = User state_11 = { "class_": User, "modified": False, "committed_state": {}, "instance": u1, "manager": manager, "key": (User, (1,)), "expired_attributes": set(), "expired": True, } state = sa_state.InstanceState.__new__(sa_state.InstanceState) state.__setstate__(state_11) eq_(state.identity_token, None) eq_(state.identity_key, (User, (1,), None))
def test_09_pickle(self): users = self.tables.users mapper(User, users) sess = Session() sess.add(User(id=1, name="ed")) sess.commit() sess.close() inst = User(id=1, name="ed") del inst._sa_instance_state state = sa_state.InstanceState.__new__(sa_state.InstanceState) state_09 = { "class_": User, "modified": False, "committed_state": {}, "instance": inst, "callables": {"name": state, "id": state}, "key": (User, (1,)), "expired": True, } manager = instrumentation._SerializeManager.__new__( instrumentation._SerializeManager ) manager.class_ = User state_09["manager"] = manager state.__setstate__(state_09) eq_(state.expired_attributes, {"name", "id"}) sess = Session() sess.add(inst) eq_(inst.name, "ed") # test identity_token expansion eq_(sa.inspect(inst).key, (User, (1,), None))
def test_set_composite_attrs_via_selectable(self): Values, CustomValues, values, Descriptions, descriptions = ( self.classes.Values, self.classes.CustomValues, self.tables.values, self.classes.Descriptions, self.tables.descriptions, ) session = Session() d = Descriptions( custom_descriptions=CustomValues("Color", "Number"), values=[ Values(custom_values=CustomValues("Red", "5")), Values(custom_values=CustomValues("Blue", "1")), ], ) session.add(d) session.commit() eq_( testing.db.execute(descriptions.select()).fetchall(), [(1, "Color", "Number")], ) eq_( testing.db.execute(values.select()).fetchall(), [(1, 1, "Red", "5"), (2, 1, "Blue", "1")], )
def test_persistence_states(self): User = self.classes.User u1 = User(name="ed") insp = inspect(u1) eq_( (insp.transient, insp.pending, insp.persistent, insp.detached), (True, False, False, False), ) s = Session(testing.db) s.add(u1) eq_( (insp.transient, insp.pending, insp.persistent, insp.detached), (False, True, False, False), ) s.flush() eq_( (insp.transient, insp.pending, insp.persistent, insp.detached), (False, False, True, False), ) s.expunge(u1) eq_( (insp.transient, insp.pending, insp.persistent, insp.detached), (False, False, False, True), )
def test_map_to_select(self): Base, Child = self.classes.Base, self.classes.Child base, child = self.tables.base, self.tables.child base_select = select([base]).alias() mapper( Base, base_select, polymorphic_on=base_select.c.type, polymorphic_identity="base", ) mapper(Child, child, inherits=Base, polymorphic_identity="child") sess = Session() # 2. use an id other than "1" here so can't rely on # the two inserts having the same id c1 = Child(id=12, name="c1") sess.add(c1) sess.commit() sess.close() c1 = sess.query(Child).one() eq_(c1.name, "c1")
def go(): session = Session(testing.db) with session.transaction: sc = SomeClass() session.add(sc) with session.begin_nested(): session.query(SomeClass).first()
def test_identity_key(self): User = self.classes.User u1 = User(name="ed") s = Session(testing.db) s.add(u1) s.flush() insp = inspect(u1) eq_(insp.identity_key, identity_key(User, (u1.id, )))
def _fixture(self): Graph, Version = self.classes.Graph, self.classes.Version sess = Session() g = Graph(Version(1, 1)) sess.add(g) sess.commit() return sess
def _unhashable_fixture(self, metadata, load_on_pending=False): class MyHashType(sa.TypeDecorator): impl = sa.String(100) def process_bind_param(self, value, dialect): return ";".join( "%s=%s" % (k, v) for k, v in sorted(value.items(), key=lambda key: key[0])) def process_result_value(self, value, dialect): return dict(elem.split("=", 1) for elem in value.split(";")) category = Table( "category", metadata, Column("id", Integer, primary_key=True), Column("data", MyHashType()), ) article = Table( "article", metadata, Column("id", Integer, primary_key=True), Column("data", MyHashType()), ) class Category(fixtures.ComparableEntity): pass class Article(fixtures.ComparableEntity): pass mapper(Category, category) mapper( Article, article, properties={ "category": relationship( Category, primaryjoin=orm.foreign(article.c.data) == category.c.data, load_on_pending=load_on_pending, ) }, ) metadata.create_all() sess = Session(autoflush=False) data = {"im": "unhashable"} a1 = Article(id=1, data=data) c1 = Category(id=1, data=data) if load_on_pending: sess.add(c1) else: sess.add_all([c1, a1]) sess.flush() if load_on_pending: sess.add(a1) return Category, Article, sess, a1, c1
def test_table_binds(self): Address, addresses, users, User = ( self.classes.Address, self.tables.addresses, self.tables.users, self.classes.User, ) # ensure tables are unbound m2 = sa.MetaData() users_unbound = users.tometadata(m2) addresses_unbound = addresses.tometadata(m2) mapper(Address, addresses_unbound) mapper( User, users_unbound, properties={ "addresses": relationship( Address, backref=backref("user", cascade="all"), cascade="all", ) }, ) Session = sessionmaker( binds={ users_unbound: self.metadata.bind, addresses_unbound: self.metadata.bind, }) sess = Session() u1 = User(id=1, name="ed") sess.add(u1) eq_( sess.query(User).filter(User.id == 1).all(), [User(id=1, name="ed")], ) sess.execute(users_unbound.insert(), params=dict(id=2, name="jack")) eq_( sess.execute( users_unbound.select(users_unbound.c.id == 2)).fetchall(), [(2, "jack")], ) eq_( sess.execute(users_unbound.select(User.id == 2)).fetchall(), [(2, "jack")], ) sess.execute(users_unbound.delete()) eq_(sess.execute(users_unbound.select()).fetchall(), []) sess.close()
def test_session_accessor(self): User = self.classes.User u1 = User(name="ed") insp = inspect(u1) is_(insp.session, None) s = Session() s.add(u1) is_(insp.session, s)
def test_replace(self): sess = Session() f1 = Foo(data={"a": "b"}) sess.add(f1) sess.flush() f1.data = {"b": "c"} sess.commit() eq_(f1.data, {"b": "c"})
def test_instance_state_ident_persistent(self): User = self.classes.User u1 = User(name="ed") s = Session(testing.db) s.add(u1) s.flush() insp = inspect(u1) eq_(insp.identity, (u1.id, )) is_(s.query(User).get(insp.identity), u1)
def test_alias_pathing(self): metadata = MetaData(self.engine) a = Table( "a", metadata, Column("id", Integer, primary_key=True, test_needs_autoincrement=True), Column("bid", Integer, ForeignKey("b.id")), Column("type", String(30)), ) asub = Table( "asub", metadata, Column("id", Integer, ForeignKey("a.id"), primary_key=True), Column("data", String(30)), ) b = Table( "b", metadata, Column("id", Integer, primary_key=True, test_needs_autoincrement=True), ) mapper(A, a, polymorphic_identity="a", polymorphic_on=a.c.type) mapper(ASub, asub, inherits=A, polymorphic_identity="asub") mapper(B, b, properties={"as_": relationship(A)}) metadata.create_all() sess = Session() a1 = ASub(data="a1") a2 = ASub(data="a2") a3 = ASub(data="a3") b1 = B(as_=[a1, a2, a3]) sess.add(b1) sess.commit() del sess # sqlite has a slow enough growth here # that we have to run it more times to see the # "dip" again @profile_memory(maxtimes=120) def go(): sess = Session() sess.query(B).options(subqueryload(B.as_.of_type(ASub))).all() sess.close() try: go() finally: metadata.drop_all() clear_mappers()
def test_round_trip_ok(self): sess = Session() f = Foo() f.data = (3, 4) sess.add(f) sess.commit() eq_(f.data, Point(3, 4))
def _persistent_m2m_fixture(self, autoflush=True, items_args={}): Order, Item = self._order_item_fixture(items_args=items_args) o1 = Order() i1 = Item(description="i1") s = Session(autoflush=autoflush) s.add(o1) s.flush() return o1, i1, s
def _test_roundtrip(self): Edge, Point = self.classes.Edge, self.classes.Point e1 = Edge(start=Point(3, 4), end=Point(5, 6)) sess = Session() sess.add(e1) sess.commit() eq_(sess.query(Edge).one(), Edge(start=Point(3, 4), end=Point(5, 6)))
def test_persist(self): A, C, B = (self.classes.A, self.classes.C, self.classes.B) sess = Session() sess.add(A(c=C("b1", B(data="b2")))) sess.commit() a1 = sess.query(A).one() eq_(a1.c, C("b1", B(data="b2")))
def insert_data(cls, connection): A, B, C, D, E, F, G = cls.classes("A", "B", "C", "D", "E", "F", "G") s = Session(connection) s.add( A( bs=[B(cs=[C(ds=[D()])]), B(cs=[C()])], es=[E(fs=[F()], gs=[G()])], )) s.commit()
def test_replace_itself_still_ok(self): sess = Session() f1 = Foo(data={"a": "b"}) sess.add(f1) sess.flush() f1.data = f1.data f1.data["b"] = "c" sess.commit() eq_(f1.data, {"a": "b", "b": "c"})
def test_set_composite_values(self): Foobar, FBComposite = self.classes.Foobar, self.classes.FBComposite sess = Session() f1 = Foobar() f1.foob = FBComposite(None, 5, None, None) sess.add(f1) sess.flush() eq_(f1.foob, FBComposite(2, 5, 15, None))
def test_unrelated_flush(self): sess = Session() f1 = Foo(data={"a": "b"}, unrelated_data="unrelated") sess.add(f1) sess.flush() f1.unrelated_data = "unrelated 2" sess.flush() f1.data["a"] = "c" sess.commit() eq_(f1.data["a"], "c")
def test_unrelated_flush(self): sess = Session() f1 = Foo(data=[1, 2], unrelated_data="unrelated") sess.add(f1) sess.flush() f1.unrelated_data = "unrelated 2" sess.flush() f1.data[0] = 3 sess.commit() eq_(f1.data[0], 3)
def test_unrelated_flush(self): sess = Session() f1 = Foo(data=set([1, 2]), unrelated_data="unrelated") sess.add(f1) sess.flush() f1.unrelated_data = "unrelated 2" sess.flush() f1.data.add(3) sess.commit() eq_(f1.data, set([1, 2, 3]))