I've tested the patch. Works perfectly with my usecase.

Thank you very much !

Le vendredi 19 juillet 2019 20:22:40 UTC+3, Mike Bayer a écrit :
>
>
>
> On Fri, Jul 19, 2019, at 4:40 AM, yoch melka wrote:
>
> Thank you for your help.
>
> I'd be happy to submit a PR (I've already tried to fix this by myself), 
> but the code is a little hard to master.
>
>
>
> I'm glad you tried.    The feature is in review at 
> https://gerrit.sqlalchemy.org/#/c/1368/. 
> <https://gerrit.sqlalchemy.org/#/c/1368/>   Of particular importance is 
> that it has a new "degrade" step in the very unlikely case that the foreign 
> key attributes on the parent object are unloaded; rather than emitting a 
> separate query for those,  it goes back to the JOIN.
>
> I would encourage you, if possible, to download the patch for the 1.3 
> series from 
> https://gerrit.sqlalchemy.org/#/c/sqlalchemy/sqlalchemy/+/1369/ and 
> ensure it works and performs as expected for your use case, though a 
> SQLAlchemy release is now overdue and this may go out quickly.
>
>
>
> Le vendredi 19 juillet 2019 01:24:03 UTC+3, Mike Bayer a écrit :
>
>
>
> On Thu, Jul 18, 2019, at 5:02 PM, yoch melka wrote:
>
> Hi,
>
> According to the documentation 
> <https://docs.sqlalchemy.org/en/13/orm/loading_relationships.html#select-in-loading>,
>  
> from 1.3 "selectin loading can omit the JOIN for a simple one-to-many 
> collection" in case if the PK is known by the primary request.
>
> But in the opposite case that we know the FK, it's not exploited by 
> Sqlalchemy to produce more effective queries.
>
> Example:
>
> from sqlalchemy import Table, Column, Integer, ForeignKey, create_engine
> from sqlalchemy.orm import relationship, sessionmaker, selectinload
> from sqlalchemy.ext.declarative import declarative_base 
>
>
> Base = declarative_base()
>
> class Parent(Base):
>     __tablename__ = 'parent'
>     id = Column(Integer, primary_key=True)
>     child_id = Column(Integer, ForeignKey('child.id'))
>     child = relationship("Child")
>
> class Child(Base):
>     __tablename__ = 'child'
>     id = Column(Integer, primary_key=True)
>
>
> engine = create_engine('sqlite://')
> engine.echo = True
>
> Base.metadata.create_all(engine)
>
> Session = sessionmaker(bind=engine)
> db=Session()
>
> # create some data
> c1 = Child()
> db.add(c1)
> for n in range(10):
>     p = Parent(child=c1)
>     db.add(p)
> db.commit()
>
>
> l = db.query(Parent).options(selectinload(Parent.child)).all()
>
> The last instruction above will produce the following two SQL queries :
>
> SELECT parent.id AS parent_id, parent.child_id AS parent_child_id 
> FROM parent
>
> SELECT parent_1.id AS parent_1_id, child.id AS child_id 
> FROM parent AS parent_1 JOIN child ON child.id = parent_1.child_id 
> WHERE parent_1.id IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
> ORDER BY parent_1.id
>
> But in fact, the ORM have enough information to made the second query 
> simply:
>
> SELECT child.id AS child_id
> FROM child
> WHERE id IN (1)
>
> because we know that all child_id we have in parents are 1.
>
> Is it can be improved ?
>
>
>
> certainly, do you have resources to work on a pull request?      it would 
> require a new method like _init_for_omit_join() [1] as well as an alternate 
> strategy inside of _load_for_path() [2] which loads the related objects, 
> and matches them to the parents, in a different way.
>
> You can get almost the same effect right now, with a little bit less 
> internal effiency,  to just load the Child objects directly in a list, then 
> access the attribute upon each Parent, which loads them from the identity 
> map:
>
> l = db.query(Parent).all()
> c = db.query(Child).filter(Child.id.in_([p.id for p in l])).all()
> for p in l:
>     p.child  # no query is emitted
>
>
> a PR for this feature could be informed by a similar strategy, though the 
> "p.child" part should likely use a faster route to populating the attribute 
> directly the way the current strategy does.
>
>
> [1] 
> https://github.com/sqlalchemy/sqlalchemy/blob/master/lib/sqlalchemy/orm/strategies.py#L2097
> [2] 
> https://github.com/sqlalchemy/sqlalchemy/blob/master/lib/sqlalchemy/orm/strategies.py#L2196
>
>
>
>
> --
> 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 sqlal...@googlegroups.com.
> To post to this group, send email to sqlal...@googlegroups.com.
> Visit this group at https://groups.google.com/group/sqlalchemy.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/sqlalchemy/b199fba3-8aaf-4e23-b406-865c3e57986c%40googlegroups.com
>  
> <https://groups.google.com/d/msgid/sqlalchemy/b199fba3-8aaf-4e23-b406-865c3e57986c%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>
>
>
> --
> 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 sqlal...@googlegroups.com <javascript:>.
> To post to this group, send email to sqlal...@googlegroups.com 
> <javascript:>.
> Visit this group at https://groups.google.com/group/sqlalchemy.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/sqlalchemy/efc5ccd1-e94a-4b13-909e-62063325f332%40googlegroups.com
>  
> <https://groups.google.com/d/msgid/sqlalchemy/efc5ccd1-e94a-4b13-909e-62063325f332%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>
>
>

-- 
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/ed876ade-52c7-46cd-b723-592358f5cc77%40googlegroups.com.

Reply via email to