the recursion_depth feature on selectinload() is also very new and that is 
actually a very complex and not very mature feature.    If you only wanted to 
apply additional options for N levels deep, you would build out separate 
options for that, like:

options(
   selectinload(Model.thing, recursion_depth=-1),
   
defaultload(Model.thing).selectinload(Model.otherthing).selectinload(Model.otherthing)
)

something like that

again, fairly esoteric stuff

On Fri, Sep 15, 2023, at 4:25 AM, Cornelis Poppema wrote:
> Hello Mike, thank you very much for the in-depth reply and providing a 
> solution :)
> 
> There is no specific reason that I posted in google groups, I did not visit 
> the support page, this was just something I decided after thinking where to 
> post first between googlegroups and stackoverflow, I will use github 
> discussions when I open a new discussion in the future!
> Your workaround will help me continue so many many thanks. I thought I tried 
> all variations, but I can only concede after seeing this work that I did not 
> attempt adding the selectinload to the root options().
> 
> It might warrant a new thread, but can you also tell me if there is a way to 
> control the options() that sqlalchemy uses for the recursion of next_step ?
> 
> Ie. I included this bit in the original post:
> ```
> .options(
>     selectinload(StepModel.next_step, recursion_depth=-1),
>     ...
> )
> ```
> 
> and it would be helpful to know if I can chain the same options to next_step, 
> so that step also has its actions and their relationships() eagerly available 
> etc.
> 
> PS
> FWIW the reason I included `raiseload("*")` in options() is because I am 
> running async queries, and personally the error I will be confronted with 
> trying to access lazy attributes is more helpful, so I've come to add it by 
> default. Without raisedload(*) I would see:
> ```
> sqlalchemy.exc.MissingGreenlet: greenlet_spawn has not been called; can't 
> call await_only() here. Was IO attempted in an unexpected place? (Background 
> on this error at: https://sqlalche.me/e/20/xd2s)
> ```
> 
> With the help of raisedload(*) I get to see:
> ```
> sqlalchemy.exc.InvalidRequestError: 'ServiceActionModel.service' is not 
> available due to lazy='raise```
> ```
> 
> This helps me tackle those cases more easily one-by-one.
> 
> On Thursday, 14 September 2023 at 15:30:23 UTC+2 Mike Bayer wrote:
>> __
>> 
>> 
>> On Thu, Sep 14, 2023, at 7:36 AM, Cornelis Poppema wrote:
>>> Hi all,
>>> 
>>> I am new to sqlalchemy, I think the idea of what I am trying to achieve is 
>>> relatively simple, but I can't seem to figure out how to retrieve 
>>> `.service` in the same query. I failed to find an example in the 2.0 
>>> documentation for exactly this.
>>> 
>>> My attempts have been to simply chain a .selectinload after the 
>>> .selectin_polymorphic, ie.:
>>> 
>>> ```python
>>>         .options(
>>>             selectinload(StepModel.next_step, recursion_depth=-1),
>>>             selectinload(StepModel.actionbases).selectin_polymorphic(
>>>                 [
>>>                     ServiceActionModel,
>>>                 ],
>>>             )
>>>             .selectinload(ServiceActionModel.service),
>>>             raiseload("*"),
>>>         )
>>> ```
>>> 
>>> This gives the error:
>>> 
>>> ```
>>> /usr/local/lib/python3.11/site-packages/sqlalchemy/orm/strategy_options.py:2442:
>>>  in _raise_for_does_not_link
>>>     raise sa_exc.ArgumentError(
>>> E   sqlalchemy.exc.ArgumentError: ORM mapped entity or attribute 
>>> "ServiceActionModel.service" does not link from relationship 
>>> "StepModel.actionbases".  Did you mean to use 
>>> "StepModel.actionbases.of_type(ServiceActionModel)"?
>>> ```
>>> 
>> 
>> Hi -
>> 
>> A few up front things, is it possible you can post these questions that have 
>> a lot of code on github discussions?   That's at 
>> https://github.com/sqlalchemy/sqlalchemy/discussions .    I'm sort of 
>> wondering how new users are still arriving here at the mailing list, did you 
>> find this list via the support page at 
>> https://www.sqlalchemy.org/support.html ?   I would want to change the 
>> verbiage there to please refer people to GH discussions instead.    
>> Especially with these advanced inheritance eager loading problems, which in 
>> the majority of cases end up being real bugs in SQLAlchemy, as seems to be 
>> the case here (at least, there is an inconsistency in the API that somehow 
>> needs to be documented, or something).
>> 
>> As for the question, first off this is really advanced usage and I've hardly 
>> ever seen people using selectin_polymorphic(), much less deep within a chain 
>> of loaders like this.
>> 
>> The correct form for this load would follow from how it's described at 
>> https://docs.sqlalchemy.org/en/20/orm/queryguide/inheritance.html#combining-additional-loader-options-with-selectin-polymorphic-subclass-loads
>>  , where the ORM allows the selectin_polymorphic(Target, [TargetSubclassA]) 
>> to be a sibling to the appropriate relationship load, 
>> selectinload(TargetSubclassA.elements).   The example there places both of 
>> these options comma-separated within select().options().    This is the 
>> "inconsistent" part because I'm already surprised the ORM is allowing the 
>> selectinload() to be present against TargetSubclassA when that's not one of 
>> the primary entities in the select().
>> 
>> However in your case, you are coming off of a parent loader option already.  
>> So following from this, the correct form based on a direct reading of those 
>> docs would, *in theory*, be:
>> 
>> select().options(
>>      selectinload(Parent.target).options(
>>              selectin_polymorphic(Target, [TargetSubclassA]),
>>              selectinload(TargetSubclassA.elements)
>>      )
>> )
>> 
>> that is, you can build up sibling options from a parent loader option using 
>> another call to .options().
>> 
>> however, this doesn't work; the validation of the loader chain 
>> unsurprisingly notes that TargetSubclass is not linked from Parent.target, 
>> and they'd like you to use of_type() instead.    So I've made a bug for this 
>> here:  https://github.com/sqlalchemy/sqlalchemy/issues/10348  as something 
>> has to change here, either the docs, or the usage pattern for 
>> selectin_polymorphic(), or the error checks have to get a lot smarter to 
>> figure this out and let this case pass, since it works fine the way you are 
>> expecting if I just have it skip the error checking.
>> 
>> What you can do now is use with_polymorphic() instead that is more 
>> configurable for this kind of loader chain:
>> 
>> TT = with_polymorphic(Target, [TargetSubclassA])
>> select().options(selectinload(Parent.target.of_type(TT).selectinload(TT.TargetSubclassA.elements)))
>> 
>> discussion can continue at the issue above or a new github discussion, 
>> thanks!
>> 
>> 
> 
> 
> -- 
> SQLAlchemy - 
> The Python SQL Toolkit and Object Relational Mapper
>  
> http://www.sqlalchemy.org/
>  
> To post example code, please provide an MCVE: Minimal, Complete, and 
> Verifiable Example. See http://stackoverflow.com/help/mcve for a full 
> description.
> --- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to sqlalchemy+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/sqlalchemy/3e4b053f-e583-4a20-98b5-abfd08479b60n%40googlegroups.com
>  
> <https://groups.google.com/d/msgid/sqlalchemy/3e4b053f-e583-4a20-98b5-abfd08479b60n%40googlegroups.com?utm_medium=email&utm_source=footer>.

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/95767929-f049-470d-ae36-7efe0a456791%40app.fastmail.com.

Reply via email to