test #6887. The one case here which would break before the bug was fixed is: use_query_cache=True, loader_opt=selectinload, key_type="fixed" Meaning with a fixed cache key and query caching in place, the user defined loader option would be cached under the same nam
(
self, key_type, loader_opt, num_opts, use_query_cache
)
| 165 | ) |
| 166 | @testing.combinations((True,), (False,), argnames="use_query_cache") |
| 167 | def test_user_option_propagation( |
| 168 | self, key_type, loader_opt, num_opts, use_query_cache |
| 169 | ): |
| 170 | """test #6887. |
| 171 | |
| 172 | The one case here which would break before the bug was fixed is: |
| 173 | |
| 174 | use_query_cache=True, loader_opt=selectinload, key_type="fixed" |
| 175 | |
| 176 | Meaning with a fixed cache key and query caching in place, the user |
| 177 | defined loader option would be cached under the same name each time, |
| 178 | leading to use of the stale option when using selectinload, as this |
| 179 | strategy transfers query options from the cached ORM select into the |
| 180 | one that it generates. no other strategy currently does this. |
| 181 | |
| 182 | """ |
| 183 | User, Address, Dinagling = self.classes("User", "Address", "Dingaling") |
| 184 | |
| 185 | class SetShardOption(UserDefinedOption): |
| 186 | propagate_to_loaders = True |
| 187 | |
| 188 | def _gen_cache_key(self, anon_map, bindparams): |
| 189 | if key_type == "fixed": |
| 190 | return (None,) |
| 191 | elif key_type == "payload": |
| 192 | return (self.payload,) |
| 193 | elif key_type == "dont_cache": |
| 194 | anon_map[NO_CACHE] = True |
| 195 | return None |
| 196 | else: |
| 197 | assert False |
| 198 | |
| 199 | if use_query_cache: |
| 200 | testing.db._compiled_cache.clear() |
| 201 | s = fixture_session() |
| 202 | else: |
| 203 | s = fixture_session( |
| 204 | bind=testing.db.execution_options(compiled_cache=None) |
| 205 | ) |
| 206 | |
| 207 | m1 = Mock() |
| 208 | |
| 209 | @event.listens_for(s, "do_orm_execute") |
| 210 | def go(context): |
| 211 | for elem in context.user_defined_options: |
| 212 | if isinstance(elem, SetShardOption): |
| 213 | m1.update_execution_options(_sa_shard_id=elem.payload) |
| 214 | |
| 215 | stmt = select(User).options( |
| 216 | loader_opt(User.addresses).options(loader_opt(Address.dingaling)), |
| 217 | SetShardOption("some_shard"), |
| 218 | ) |
| 219 | for u in s.execute(stmt).unique().scalars(): |
| 220 | for a in u.addresses: |
| 221 | a.dingaling |
| 222 | |
| 223 | s.close() |
| 224 |
nothing calls this directly
no test coverage detected