def test_update_preserve_parameter_order(self): User = self.classes.User session = Session() # Do update using a tuple and check that order is preserved q = session.query(User) with mock.patch.object(q, "_execute_crud") as exec_: q.filter(User.id == 15).update( (("id", 123), ("name", "foob")), update_args={"preserve_parameter_order": True}, ) cols = [ c.key for c in exec_.mock_calls[0][1][0]._parameter_ordering ] eq_(["id", "name"], cols) # Now invert the order and use a list instead, and check that order is # also preserved q = session.query(User) with mock.patch.object(q, "_execute_crud") as exec_: q.filter(User.id == 15).update( [("name", "foob"), ("id", 123)], update_args={"preserve_parameter_order": True}, ) cols = [ c.key for c in exec_.mock_calls[0][1][0]._parameter_ordering ] eq_(["name", "id"], cols)
def test_bundle_nesting_unions(self): Data = self.classes.Data sess = Session() b1 = Bundle("b1", Data.d1, Bundle("b2", Data.d2, Data.d3)) q1 = (sess.query(b1).filter(b1.c.d1.between("d3d1", "d7d1")).filter( b1.c.b2.c.d2.between("d4d2", "d5d2"))) q2 = (sess.query(b1).filter(b1.c.d1.between("d3d1", "d7d1")).filter( b1.c.b2.c.d2.between("d5d2", "d6d2"))) eq_( q1.union(q2).all(), [ (("d4d1", ("d4d2", "d4d3")), ), (("d5d1", ("d5d2", "d5d3")), ), (("d6d1", ("d6d2", "d6d3")), ), ], ) # naming structure is preserved row = q1.union(q2).first() eq_(row.b1.d1, "d4d1") eq_(row.b1.b2.d2, "d4d2")
def test_bulk_save_updated_include_unchanged(self): (User, ) = self.classes("User") s = Session(expire_on_commit=False) objects = [User(name="u1"), User(name="u2"), User(name="u3")] s.add_all(objects) s.commit() objects[0].name = "u1new" objects[2].name = "u3new" s = Session() with self.sql_execution_asserter() as asserter: s.bulk_save_objects(objects, update_changed_only=False) asserter.assert_( CompiledSQL( "UPDATE users SET name=:name WHERE " "users.id = :users_id", [ { "users_id": 1, "name": "u1new" }, { "users_id": 2, "name": "u2" }, { "users_id": 3, "name": "u3new" }, ], ))
def test_meta_getattr_three(self): class MetaPoint(type): def __getattr__(cls, key): @hybrid_property def double_x(me): return me.x * 2 if key == "double_x": return double_x.__get__(None, cls) raise AttributeError(key) class Point(compat.with_metaclass(MetaPoint)): pass self._fixture(Point) alias = aliased(Point) eq_(str(Point.double_x.__clause_element__()), "point.x * :x_1") eq_(str(alias.double_x.__clause_element__()), "point_1.x * :x_1") sess = Session() self.assert_compile( sess.query(alias).filter(alias.double_x > Point.x), "SELECT point_1.id AS point_1_id, point_1.x AS point_1_x, " "point_1.y AS point_1_y FROM point AS point_1, point " "WHERE point_1.x * :x_1 > point.x", )
def test_subclass(self): Data = self.classes.Data sess = Session() class MyBundle(Bundle): def create_row_processor(self, query, procs, labels): def proc(row): return dict(zip(labels, (proc(row) for proc in procs))) return proc b1 = MyBundle("b1", Data.d1, Data.d2) eq_( sess.query(b1).filter(b1.c.d1.between("d3d1", "d5d1")).all(), [ ({ "d2": "d3d2", "d1": "d3d1" }, ), ({ "d2": "d4d2", "d1": "d4d1" }, ), ({ "d2": "d5d2", "d1": "d5d1" }, ), ], )
def test_any_wpoly(self): DataContainer, Job, SubJob = ( self.classes.DataContainer, self.classes.Job, self.classes.SubJob, ) Job_P = with_polymorphic(Job, SubJob, aliased=True, flat=True) s = Session() q = (s.query(Job).join(DataContainer.jobs).filter( DataContainer.jobs.of_type(Job_P).any(Job_P.id < Job.id))) self.assert_compile( q, "SELECT job.id AS job_id, job.type AS job_type, " "job.widget_id AS job_widget_id, " "job.container_id " "AS job_container_id " "FROM data_container " "JOIN job ON data_container.id = job.container_id " "WHERE EXISTS (SELECT 1 " "FROM job AS job_1 LEFT OUTER JOIN subjob AS subjob_1 " "ON job_1.id = subjob_1.id " "WHERE data_container.id = job_1.container_id " "AND job_1.id < job.id)", )
def test_hybrid_descriptor_two(self): class Point(object): def __init__(self, x, y): self.x, self.y = x, y @hybrid_property def double_x(self): return self.x * 2 self._fixture(Point) alias = aliased(Point) eq_(str(Point.double_x), "Point.double_x") eq_(str(alias.double_x), "AliasedClass_Point.double_x") eq_(str(Point.double_x.__clause_element__()), "point.x * :x_1") eq_(str(alias.double_x.__clause_element__()), "point_1.x * :x_1") sess = Session() self.assert_compile( sess.query(alias).filter(alias.double_x > Point.x), "SELECT point_1.id AS point_1_id, point_1.x AS point_1_x, " "point_1.y AS point_1_y FROM point AS point_1, point " "WHERE point_1.x * :x_1 > point.x", )
def test_aliased_query_col(self): A = self._fixture() sess = Session() self.assert_compile( sess.query(aliased(A).value(5)), "SELECT foo(a_1.value, :foo_1) + :foo_2 AS anon_1 FROM a AS a_1", )
def test_aliased_query(self): A = self._fixture() sess = Session() self.assert_compile( sess.query(aliased(A).value), "SELECT a_1.value AS a_1_value FROM a AS a_1", )
def test_get_pk_w_null(self): """test the re-implementation of logic to do get with IS NULL.""" class AddressUser(object): pass mapper( AddressUser, self.tables.users.outerjoin(self.tables.addresses), properties={ "id": self.tables.users.c.id, "address_id": self.tables.addresses.c.id, }, ) bq = self.bakery(lambda s: s.query(AddressUser)) sess = Session() def go(): u1 = bq(sess).get((10, None)) eq_(u1.name, "chuck") self.assert_sql_count(testing.db, go, 1) u1 = sess.query(AddressUser).get((10, None)) # noqa def go(): u2 = bq(sess).get((10, None)) eq_(u2.name, "chuck") self.assert_sql_count(testing.db, go, 0)
def test_query_col(self): A = self._fixture() sess = Session() self.assert_compile( sess.query(A.value(5)), "SELECT foo(a.value, :foo_1) + :foo_2 AS anon_1 FROM a", )
def test_get(self): User = self.classes.User bq = self.bakery(lambda s: s.query(User)) sess = Session() def go(): u1 = bq(sess).get(7) eq_(u1.name, "jack") self.assert_sql_count(testing.db, go, 1) u1 = sess.query(User).get(7) # noqa def go(): u2 = bq(sess).get(7) eq_(u2.name, "jack") self.assert_sql_count(testing.db, go, 0) def go(): u2 = bq(sess).get(8) eq_(u2.name, "ed") self.assert_sql_count(testing.db, go, 1)
def _test_baked_lazy_loading_relationship_flag(self, flag): User, Address = self._o2m_fixture(bake_queries=flag) sess = Session() u1 = sess.query(User).first() from sqlalchemy_1_3.orm import Query canary = mock.Mock() # I would think Mock can do this but apparently # it cannot (wrap / autospec don't work together) real_compile_context = Query._compile_context def _my_compile_context(*arg, **kw): if arg[0].column_descriptions[0]["entity"] is Address: canary() return real_compile_context(*arg, **kw) with mock.patch.object(Query, "_compile_context", _my_compile_context): u1.addresses sess.expire(u1) u1.addresses if flag: eq_(canary.call_count, 1) else: eq_(canary.call_count, 2)
def test_update_from_multitable_same_names(self): Document = self.classes.Document User = self.classes.User s = Session() s.query(Document).filter(User.id == Document.user_id).filter( User.id == 2).update( { Document.samename: "d_samename", User.samename: "u_samename" }, synchronize_session=False, ) eq_( s.query(User.id, Document.samename, User.samename).filter( User.id == Document.user_id).order_by(User.id).all(), [ (1, None, None), (1, None, None), (2, "d_samename", "u_samename"), (2, "d_samename", "u_samename"), (3, None, None), (3, None, None), ], )
def test_selectinload(self): A, B = self.classes("A", "B") sess = Session() with self.sql_execution_asserter() as asserter: # note this is many-to-one. use_get is unconditionally turned # off for relationship to aliased class for now. a1 = sess.query(A).options(selectinload(A.b)).first() eq_(a1.b, B(id=1)) asserter.assert_( CompiledSQL( "SELECT a.id AS a_id, a.b_id AS a_b_id " "FROM a LIMIT :param_1", [{ "param_1": 1 }], ), CompiledSQL( "SELECT a_1.id AS a_1_id, b.id AS b_id FROM a AS a_1 " "JOIN (b JOIN d ON d.b_id = b.id JOIN c ON c.id = d.c_id) " "ON a_1.b_id = b.id WHERE a_1.id " "IN ([EXPANDING_primary_keys])", [{ "primary_keys": [1] }], ), )
def test_partial_load_no_invoke_eagers(self): # test issue #4199 self._fixture_from_geometry( { "a": { "subclasses": { "a1": {"polymorphic_load": "selectin"}, "a2": {"polymorphic_load": "selectin"}, } } } ) a, a1, a2 = self.classes("a", "a1", "a2") sess = Session() a1_obj = a1() a2_obj = a2() sess.add_all([a1_obj, a2_obj]) del a2_obj sess.flush() sess.expire_all() # _with_invoke_all_eagers(False), used by the lazy loader # strategy, will cause one less state to be present such that # the poly loader won't locate a state limited to the "a1" mapper, # needs to test that it has states sess.query(a)._with_invoke_all_eagers(False).all()
def test_joinedload_explicit_with_flataliased_poly_compile(self): sess = Session() target = with_polymorphic(Person, Engineer, flat=True) q = (sess.query(Company).filter_by(company_id=1).options( joinedload(Company.employees.of_type(target)))) self.assert_compile( q, "SELECT companies.company_id AS companies_company_id, " "companies.name AS companies_name, " "people_1.person_id AS people_1_person_id, " "people_1.company_id AS people_1_company_id, " "people_1.name AS people_1_name, people_1.type AS people_1_type, " "engineers_1.person_id AS engineers_1_person_id, " "engineers_1.status AS engineers_1_status, " "engineers_1.engineer_name AS engineers_1_engineer_name, " "engineers_1.primary_language AS engineers_1_primary_language " "FROM companies LEFT OUTER JOIN (people AS people_1 " "LEFT OUTER JOIN engineers AS engineers_1 " "ON people_1.person_id = engineers_1.person_id " "LEFT OUTER JOIN managers AS managers_1 " "ON people_1.person_id = managers_1.person_id) " "ON companies.company_id = people_1.company_id " "WHERE companies.company_id = :company_id_1 " "ORDER BY people_1.person_id", )
def test_bulk_save_return_defaults(self): (User, ) = self.classes("User") s = Session() objects = [User(name="u1"), User(name="u2"), User(name="u3")] assert "id" not in objects[0].__dict__ with self.sql_execution_asserter() as asserter: s.bulk_save_objects(objects, return_defaults=True) asserter.assert_( CompiledSQL("INSERT INTO users (name) VALUES (:name)", [{ "name": "u1" }]), CompiledSQL("INSERT INTO users (name) VALUES (:name)", [{ "name": "u2" }]), CompiledSQL("INSERT INTO users (name) VALUES (:name)", [{ "name": "u3" }]), ) eq_(objects[0].__dict__["id"], 1)
def test_delete_against_metadata(self): User = self.classes.User users = self.tables.users sess = Session() sess.query(users).delete(synchronize_session=False) eq_(sess.query(User).count(), 0)
def _assert( self, read=False, nowait=False, of=None, key_share=None, assert_q_of=None, assert_sel_of=None, ): User = self.classes.User s = Session() q = s.query(User).with_for_update( read=read, nowait=nowait, of=of, key_share=key_share ) sel = q._compile_context().statement assert q._for_update_arg.read is read assert sel._for_update_arg.read is read assert q._for_update_arg.nowait is nowait assert sel._for_update_arg.nowait is nowait assert q._for_update_arg.key_share is key_share assert sel._for_update_arg.key_share is key_share eq_(q._for_update_arg.of, assert_q_of) eq_(sel._for_update_arg.of, assert_sel_of)
def test_callable_bind(self): Address, addresses, users, User = ( self.classes.Address, self.tables.addresses, self.tables.users, self.classes.User, ) mapper( User, users, properties=dict(addresses=relationship( mapper(Address, addresses), lazy="select", primaryjoin=and_( users.c.id == addresses.c.user_id, users.c.name == bindparam("name", callable_=lambda: "ed"), ), )), ) s = Session() ed = s.query(User).filter_by(name="ed").one() eq_( ed.addresses, [ Address(id=2, user_id=8), Address(id=3, user_id=8), Address(id=4, user_id=8), ], ) fred = s.query(User).filter_by(name="fred").one() eq_(fred.addresses, []) # fred is missing
def test_mysql_read(self): User = self.classes.User sess = Session() self.assert_compile( sess.query(User.id).with_for_update(read=True), "SELECT users.id AS users_id FROM users LOCK IN SHARE MODE", dialect="mysql", )
def test_oracle_update_skip_locked(self): User = self.classes.User sess = Session() self.assert_compile( sess.query(User.id).with_for_update(skip_locked=True), "SELECT users.id AS users_id FROM users FOR UPDATE SKIP LOCKED", dialect="oracle", )
def test_oracle_update(self): User = self.classes.User sess = Session() self.assert_compile( sess.query(User.id).with_for_update(), "SELECT users.id AS users_id FROM users FOR UPDATE", dialect="oracle", )
def test_postgres_for_no_key_nowait_update(self): User = self.classes.User sess = Session() self.assert_compile( sess.query(User.id).with_for_update(key_share=True, nowait=True), "SELECT users.id AS users_id FROM users FOR NO KEY UPDATE NOWAIT", dialect="postgresql", )
def test_postgres_update_of_entity(self): User = self.classes.User sess = Session() self.assert_compile( sess.query(User.id).with_for_update(of=User), "SELECT users.id AS users_id FROM users FOR UPDATE OF users", dialect="postgresql", )
def test_postgres_read_nowait(self): User = self.classes.User sess = Session() self.assert_compile( sess.query(User.id).with_for_update(read=True, nowait=True), "SELECT users.id AS users_id FROM users FOR SHARE NOWAIT", dialect="postgresql", )
def test_not_supported_by_dialect_should_just_use_update(self): User = self.classes.User sess = Session() self.assert_compile( sess.query(User.id).with_for_update(read=True), "SELECT users.id AS users_id FROM users FOR UPDATE", dialect=default.DefaultDialect(), )
def test_default_update(self): User = self.classes.User sess = Session() self.assert_compile( sess.query(User.id).with_for_update(), "SELECT users.id AS users_id FROM users FOR UPDATE", dialect=default.DefaultDialect(), )
def test_lazyload_people_other_exists(self): self._fixture(True) City = self.classes.City sess = Session(testing.db) c1, c2 = sess.query(City).order_by(City.id).all() eq_([p.id for p in c1.people], [1, 2]) eq_([p.id for p in c2.people], [])