--- /dev/null
+.. change::
+ :tags: orm, usecase
+ :tickets: 13309
+
+ Updated the attribute :attr:`_orm.ORMExecuteState.user_defined_options` to
+ include options that were added to the statement before calling
+ :meth:`.Select.with_only_columns` or :meth:`_orm.Query.with_entities`.
"""The sequence of :class:`.UserDefinedOptions` that have been
associated with the statement being invoked.
+ .. versionchanged:: 2.1 - the returned option take into
+ consideration any options added before calling
+ :meth:`_sql.Select.with_only_columns` or
+ :meth:`_orm.Query.with_entities`.
+
"""
+ items = [
+ self.statement,
+ *getattr(self.statement, "_memoized_select_entities", ()),
+ ]
return [
opt
- for opt in self.statement._with_options
+ for item in items
+ for opt in item._with_options
if is_user_defined_option(opt)
]
),
)
+ @testing.combinations("select", "query", "not-select")
+ def test_user_option_propagation_after_with_only_columns(self, operation):
+ User = self.classes("User")[0]
+
+ class MyOption(UserDefinedOption):
+ pass
+
+ s = fixture_session()
+ found = False
+
+ @event.listens_for(s, "do_orm_execute")
+ def go(context):
+ nonlocal found
+ for elem in context.user_defined_options:
+ if isinstance(elem, MyOption):
+ found = True
+
+ if operation == "select":
+ stmt = select(User).options(MyOption()).with_only_columns(User.id)
+ s.execute(stmt).all()
+ elif operation == "query":
+ stmt = s.query(User).options(MyOption()).with_entities(User.id)
+ stmt.all()
+ elif operation == "not-select":
+ stmt = insert(User).values(name="new name").options(MyOption())
+ s.execute(stmt)
+
+ eq_(found, True)
+
def test_override_parameters_scalar(self):
"""test that session.scalar() maintains the 'scalar-ness' of the
result when using re-execute events.