On Mon, Apr 24, 2017 at 10:26 PM, Jonathan Vanasco
<jonat...@findmeon.com> wrote:
>
> On Monday, April 24, 2017 at 4:28:22 PM UTC-4, Mike Bayer wrote:
>>
>> yeah just load the object again w/ the eagerloads option you want.
>
>
>
> Thanks.  I was hoping there was a way to just say `Obj.load('foo')` ?
>
> I'll just untangle the code and load the relationship in the first place.
> At this point in the code, I don't have a session handy; grabbing it from
> the object isn't preferred for maintenance/readability.
>

Writing that Obj.load function is pretty simple. If you can make some
assumptions about the sorts of objects you will pass to it (eg. that
they always have an "id" column), it's even simpler:

def reload(instance, *options):
    session = saorm.object_session(instance)
    # TODO: make this generic rather than assuming presence of 'id' column
    q = (session.query(type(instance))
         .filter_by(id=instance.id)
         .options(*options))
    return q.one()

(I don't really understand the concern about grabbing the session from
the object)

Here's a script to show it in action:

import sqlalchemy as sa
import sqlalchemy.orm as saorm
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Root(Base):
    __tablename__ = 'root'
    id = sa.Column(sa.Integer, primary_key=True)
    name = sa.Column(sa.String())

class Bar(Base):
    __tablename__ = 'bar'
    id = sa.Column(sa.Integer, primary_key=True)
    rootid = sa.Column(sa.ForeignKey(Root.id))
    root = saorm.relationship(Root, backref='bars')

class Widget(Base):
    __tablename__ = 'widget'
    id = sa.Column(sa.Integer, primary_key=True)
    barid = sa.Column(sa.ForeignKey(Bar.id))
    bar = saorm.relationship(Bar, backref='widgets')

def reload(instance, *options):
    session = saorm.object_session(instance)
    # TODO: make this generic rather than assuming presence of 'id' column
    q = (session.query(type(instance))
         .filter_by(id=instance.id)
         .options(*options))
    return q.one()

def loadchildren(root):
    i = 0
    for bar in root.bars:
        for widget in bar.widgets:
            i += 1
    print 'loaded %s widgets' % i

if __name__ == '__main__':
    engine = sa.create_engine('sqlite:///', echo=True)
    Base.metadata.create_all(engine)
    Session = saorm.sessionmaker(bind=engine)

    s = Session()
    root = Root()
    for i in range(5):
        bar = Bar()
        root.bars.append(bar)
        for j in range(5):
            bar.widgets.append(Widget())
    s.add(root)
    s.commit()
    s.close()

    print '########### without eagerloading ###########'
    s = Session()
    root = s.query(Root).one()
    loadchildren(root)

    print '############ with eagerloading #############'
    s = Session()
    root = s.query(Root).one()
    reload(root, saorm.joinedload('bars').joinedload('widgets'))
    loadchildren(root)

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

Reply via email to