|
3 | 3 | import sqlalchemy
|
4 | 4 | from promise import dataloader, promise
|
5 | 5 | from sqlalchemy.ext.hybrid import hybrid_property
|
6 |
| -from sqlalchemy.inspection import inspect as sqlalchemyinspect |
7 |
| -from sqlalchemy.orm import (ColumnProperty, CompositeProperty, Load, |
| 6 | +from sqlalchemy.orm import (ColumnProperty, CompositeProperty, |
8 | 7 | RelationshipProperty, Session)
|
9 | 8 | from sqlalchemy.orm.exc import NoResultFound
|
10 |
| -from sqlalchemy.orm.loading import PostLoad |
| 9 | +from sqlalchemy.orm.query import QueryContext |
| 10 | +from sqlalchemy.orm.strategies import SelectInLoader |
| 11 | +from sqlalchemy.orm.util import PathRegistry |
11 | 12 |
|
12 | 13 | from graphene import Field
|
13 | 14 | from graphene.relay import Connection, Node
|
@@ -106,7 +107,7 @@ def construct_fields(
|
106 | 107 | :param function connection_field_factory:
|
107 | 108 | :rtype: OrderedDict[str, graphene.Field]
|
108 | 109 | """
|
109 |
| - inspected_model = sqlalchemyinspect(model) |
| 110 | + inspected_model = sqlalchemy.inspect(model) |
110 | 111 | # Gather all the relevant attributes from the SQLAlchemy model in order
|
111 | 112 | all_model_attrs = OrderedDict(
|
112 | 113 | inspected_model.column_attrs.items() +
|
@@ -262,46 +263,24 @@ def batch_load_fn(self, parents): # pylint: disable=method-hidden
|
262 | 263 | # The behavior of `selectin` is undefined if the parent is dirty
|
263 | 264 | assert parent not in session.dirty
|
264 | 265 |
|
265 |
| - load = Load(parent_mapper.entity).selectinload(model_attr) |
266 |
| - query = session.query(parent_mapper.entity).options(load) |
267 |
| - |
268 |
| - # Taken from orm.query.Query.__iter__ |
269 |
| - # https://git.io/JeuBi |
270 |
| - context = query._compile_context() |
271 |
| - |
272 |
| - # Taken from orm.loading.instances |
273 |
| - # https://git.io/JeuBR |
274 |
| - context.post_load_paths = {} |
275 |
| - |
276 |
| - # Taken from orm.strategies.SelectInLoader.__init__ |
277 |
| - # https://git.io/JeuBd |
278 |
| - selectin_strategy = getattr(parent_mapper.entity, model_attr).property._get_strategy(load.strategy) |
279 |
| - |
280 |
| - # Taken from orm.loading._instance_processor._instance |
281 |
| - # https://git.io/JeuBq |
282 |
| - post_load = PostLoad() |
283 |
| - post_load.loaders[model_attr] = ( |
284 |
| - model_attr, |
285 |
| - parent_mapper, |
286 |
| - selectin_strategy._load_for_path, |
287 |
| - (child_mapper,), |
288 |
| - {}, |
289 |
| - ) |
| 266 | + loader = SelectInLoader(relationship_prop, (('lazy', 'selectin'),)) |
290 | 267 |
|
291 |
| - # Taken from orm.loading._instance_processor._instance |
292 |
| - # https://git.io/JeuBn |
293 |
| - # https://git.io/Jeu4j |
294 |
| - context.partials = {} |
295 |
| - for parent in parents: |
296 |
| - post_load.add_state(parent._sa_instance_state, True) |
| 268 | + # The path is a fixed single token in this case |
| 269 | + path = PathRegistry.root + parent_mapper._path_registry |
297 | 270 |
|
298 |
| - # Taken from orm.strategies.SelectInLoader.create_row_processor |
299 |
| - # https://git.io/Jeu4F |
300 |
| - selectin_path = context.query._current_path + parent_mapper._path_registry |
| 271 | + # Should the boolean be set to False? Does it matter for our purposes? |
| 272 | + states = [(sqlalchemy.inspect(parent), True) for parent in parents] |
301 | 273 |
|
302 |
| - # Taken from orm.loading.instances |
303 |
| - # https://git.io/JeuBO |
304 |
| - post_load.invoke(context, selectin_path.path) |
| 274 | + # For our purposes, the query_context will only used to get the session |
| 275 | + query_context = QueryContext(session.query(parent_mapper.entity)) |
| 276 | + |
| 277 | + loader._load_for_path( |
| 278 | + query_context, |
| 279 | + path, |
| 280 | + states, |
| 281 | + None, |
| 282 | + child_mapper, |
| 283 | + ) |
305 | 284 |
|
306 | 285 | return promise.Promise.resolve([getattr(parent, model_attr) for parent in parents])
|
307 | 286 |
|
|
0 commit comments