_parent_execute_state=self,
)
+ @property
+ def bind_mapper(self):
+ """Return the :class:`_orm.Mapper` that is the primary "bind" mapper.
+
+ For an :class:`_orm.ORMExecuteState` object invoking an ORM
+ statement, that is, the :attr:`_orm.ORMExecuteState.is_orm_statement`
+ attribute is ``True``, this attribute will return the
+ :class:`_orm.Mapper` that is considered to be the "primary" mapper
+ of the statement. The term "bind mapper" refers to the fact that
+ a :class:`_orm.Session` object may be "bound" to multiple
+ :class:`_engine.Engine` objects keyed to mapped classes, and the
+ "bind mapper" determines which of those :class:`_engine.Engine` objects
+ would be selected.
+
+ For a statement that is invoked against a single mapped class,
+ :attr:`_orm.ORMExecuteState.bind_mapper` is intended to be a reliable
+ way of getting this mapper.
+
+ .. versionadded:: 1.4.0b2
+
+ .. seealso::
+
+ :attr:`_orm.ORMExecuteState.all_mappers`
+
+
+ """
+ return self.bind_arguments.get("mapper", None)
+
+ @property
+ def all_mappers(self):
+ """Return a sequence of all :class:`_orm.Mapper` objects that are
+ involved at the top level of this statement.
+
+ By "top level" we mean those :class:`_orm.Mapper` objects that would
+ be represented in the result set rows for a :func:`_sql.select`
+ query, or for a :func:`_dml.update` or :func:`_dml.delete` query,
+ the mapper that is the main subject of the UPDATE or DELETE.
+
+ .. versionadded:: 1.4.0b2
+
+ .. seealso::
+
+ :attr:`_orm.ORMExecuteState.bind_mapper`
+
+
+
+ """
+ if not self.is_orm_statement:
+ return []
+ elif self.is_select:
+ result = []
+ seen = set()
+ for d in self.statement.column_descriptions:
+ ent = d["entity"]
+ if ent:
+ insp = inspect(ent, raiseerr=False)
+ if insp and insp.mapper and insp.mapper not in seen:
+ seen.add(insp.mapper)
+ result.append(insp.mapper)
+ return result
+ elif self.is_update or self.is_delete:
+ return [self.bind_mapper]
+ else:
+ return []
+
@property
def is_orm_statement(self):
"""return True if the operation is an ORM statement.
from sqlalchemy import delete
from sqlalchemy import event
from sqlalchemy import ForeignKey
+from sqlalchemy import inspect
from sqlalchemy import Integer
from sqlalchemy import literal_column
from sqlalchemy import select
)
canary.options(
+ bind_mapper=ctx.bind_mapper,
+ all_mappers=ctx.all_mappers,
is_select=ctx.is_select,
is_update=ctx.is_update,
is_delete=ctx.is_delete,
return canary
+ def test_all_mappers_accessor_one(self):
+ User, Address = self.classes("User", "Address")
+
+ sess = Session(testing.db, future=True)
+
+ canary = self._flag_fixture(sess)
+
+ sess.execute(
+ select(User.id, Address.email_address, User.name)
+ .join(Address)
+ .filter_by(id=7)
+ )
+
+ eq_(
+ canary.mock_calls,
+ [
+ call.options(
+ bind_mapper=inspect(User),
+ all_mappers=[inspect(User), inspect(Address)],
+ is_select=True,
+ is_update=False,
+ is_delete=False,
+ is_orm_statement=True,
+ is_relationship_load=False,
+ is_column_load=False,
+ lazy_loaded_from=None,
+ )
+ ],
+ )
+
+ def test_all_mappers_accessor_two(self):
+
+ sess = Session(testing.db, future=True)
+
+ canary = self._flag_fixture(sess)
+
+ sess.execute(select(self.tables.users).filter_by(id=7))
+
+ eq_(
+ canary.mock_calls,
+ [
+ call.options(
+ bind_mapper=None,
+ all_mappers=[],
+ is_select=True,
+ is_update=False,
+ is_delete=False,
+ is_orm_statement=False,
+ is_relationship_load=False,
+ is_column_load=False,
+ lazy_loaded_from=None,
+ )
+ ],
+ )
+
+ def test_all_mappers_accessor_three(self):
+ User, Address = self.classes("User", "Address")
+
+ sess = Session(testing.db, future=True)
+
+ canary = self._flag_fixture(sess)
+
+ sess.execute(select(User).join(Address).filter_by(id=7))
+
+ eq_(
+ canary.mock_calls,
+ [
+ call.options(
+ bind_mapper=inspect(User),
+ all_mappers=[inspect(User)], # Address not in results
+ is_select=True,
+ is_update=False,
+ is_delete=False,
+ is_orm_statement=True,
+ is_relationship_load=False,
+ is_column_load=False,
+ lazy_loaded_from=None,
+ )
+ ],
+ )
+
def test_select_flags(self):
User, Address = self.classes("User", "Address")
canary.mock_calls,
[
call.options(
+ bind_mapper=inspect(User),
+ all_mappers=[inspect(User)],
is_select=True,
is_update=False,
is_delete=False,
lazy_loaded_from=None,
),
call.options(
+ bind_mapper=inspect(User),
+ all_mappers=[inspect(User)],
is_select=True,
is_update=False,
is_delete=False,
canary.mock_calls,
[
call.options(
+ bind_mapper=inspect(User),
+ all_mappers=[inspect(User)],
is_select=True,
is_update=False,
is_delete=False,
lazy_loaded_from=None,
),
call.options(
+ bind_mapper=inspect(Address),
+ all_mappers=[inspect(Address)],
is_select=True,
is_update=False,
is_delete=False,
canary.mock_calls,
[
call.options(
+ bind_mapper=inspect(User),
+ all_mappers=[inspect(User)],
is_select=True,
is_update=False,
is_delete=False,
lazy_loaded_from=None,
),
call.options(
+ bind_mapper=inspect(Address),
+ all_mappers=[inspect(Address)],
is_select=True,
is_update=False,
is_delete=False,
canary.mock_calls,
[
call.options(
+ bind_mapper=inspect(User),
+ all_mappers=[inspect(User)],
is_select=True,
is_update=False,
is_delete=False,
lazy_loaded_from=None,
),
call.options(
+ bind_mapper=inspect(Address),
+ all_mappers=[inspect(Address), inspect(User)],
is_select=True,
is_update=False,
is_delete=False,
canary.mock_calls,
[
call.options(
+ bind_mapper=inspect(User),
+ all_mappers=[inspect(User)],
is_select=False,
is_update=False,
is_delete=True,
lazy_loaded_from=None,
),
call.options(
+ bind_mapper=inspect(User),
+ all_mappers=[inspect(User)],
is_select=False,
is_update=True,
is_delete=False,