Can't locate strategy for ... (('lazy', 'joined'),)

1,682 views
Skip to first unread message

Russ

unread,
May 21, 2015, 3:25:10 PM5/21/15
to sqlal...@googlegroups.com
I have a query I am running where sqlalchemy is throwing this exception:

Exception: can't locate strategy for <class 'sqlalchemy.orm.properties.ColumnProperty'> (('lazy', 'joined'),)

What causes this is the addition of this joinedload_all option to a query (q):

q = q.options(sa.orm.joinedload_all("defined_items.child_product.number"))

The intent of adding that is to try and avoid emitting sql when accessing foo.defined_items[x].child_product.number, as there are many defined_items.

There are several other joined loads on this query that don't have an issue.  Any ideas on what would be causing this particular problem?

Mike Bayer

unread,
May 21, 2015, 3:38:33 PM5/21/15
to sqlal...@googlegroups.com
nope.  I'd need a complete, self-contained and succinct example I can run, thanks.




--
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+...@googlegroups.com.
To post to this group, send email to sqlal...@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Russ

unread,
May 21, 2015, 3:56:08 PM5/21/15
to sqlal...@googlegroups.com
nope.  I'd need a complete, self-contained and succinct example I can run, thanks

Ok, thanks.  This is a beefy one so that will be extremely tricky to extract.  I had hoped that the combo of lazy+joined would have been a clear indicator since they are opposite loading strategies.

Digging through the relationship definitions I thought it might be because the child_product relationship is explicitly declared with "lazy = True" ('select') and (since I don't do that on other properties) I thought perhaps that was conflicting with the later joinedload request and confusing the strategy lookup.  However, I see that True/select is the default, and I explicitly request joinedload at query time on other relationships/properties without issue, so that can't be it.  I'm stumped again.

Mike Bayer

unread,
May 21, 2015, 4:01:16 PM5/21/15
to sqlal...@googlegroups.com


On 5/21/15 3:56 PM, Russ wrote:
nope.  I'd need a complete, self-contained and succinct example I can run, thanks

Ok, thanks.  This is a beefy one so that will be extremely tricky to extract.  I had hoped that the combo of lazy+joined would have been a clear indicator since they are opposite loading strategies.

the word "lazy" there is the name of the field. It is the internal equivalent to the "lazy" argument on relationship: 

http://docs.sqlalchemy.org/en/rel_1_0/orm/relationship_api.html?highlight=relationship#sqlalchemy.orm.relationship.params.lazy

that said, here is exactly what will cause your error.     Any of the attribute names "defined_items", "child_product" or "number" are not in fact bound to a relationship(), and instead refer to a Column-mapped attribute.  Looks a lot like "number" here is a Column.  Is that the case?  You can't call joinedload for a column attribute.  


Russ

unread,
May 21, 2015, 4:19:56 PM5/21/15
to sqlal...@googlegroups.com
Yes, 'number' is a column, as you surmised.  When I drop that from the path it works fine.  The only remaining problem is/was that this ends up loading in every field in the child_product table, and this includes a potentially massive BSON column (and more).

After looking into this, I've now learned about deferred, defer, undefer, loadonly, etc.  This seems to be the correct way to manage this, and it appears to be working fine:

q = q.options(sa.orm
              .joinedload("defined_items")
              .joinedload("child_product")
              .load_only("number")
              )

Thanks for pointing me in the right direction!  This page had the info I needed:

Russ
Reply all
Reply to author
Forward
0 new messages