OK, the first load is expected, because when you 
session.query(X).options(someload(X.y)), the query will load all the ".y" for 
objects that it finds already in the identity map, however it will not 
establish someload() as a new permanent option on that X going forward, so 
subsequent loads use the default loader. if 
session.query(X).options(someload(X.y)) actually created the new X, then the 
someload() option is permanently associated with it. I understand this is not 
completely clear but historically, all of these loader options were just 
optimizations and it wasn't the end of the world if in some refresh 
circumstances, they didn't take effect. however with lazy='raise' it's a much 
bigger source of confusion.

There's an additional issue which is that in current 1.3 series, the call to 
refresh() does not make use of the loaders that were applied to the object . So 
for current releases, it still wont work for you; the load after the refresh() 
will fail even if the X was just loaded. However for 1.4 , it will work, due to 
https://docs.sqlalchemy.org/en/14/changelog/migration_14.html#change-1763 .

short answer is that in 1.3 if you are using lazy="raise", the object won't 
really have flexibility in being able to actually load that attribute other 
than accessing it with a query. if you want, you can use this pattern, which 
should work everywhere:

session.query(Group).populate_existing().options(lazyload(Group.users)).get(group.id)

that also will apply the lazyload() option to the Group object permanently 
unless populate_existing() is used on it again.




On Wed, Sep 25, 2019, at 3:57 PM, Mike Bayer wrote:
> what you are seeing is somewhat backwards due to what might be a bug. in the 
> example you have, *both* calls to group.users should be raising, because this 
> object is already present in the identity map so your lazyload() option 
> should not affect this already-present Group object.
> 
> if you load the Group newly into a new Session, or session.close() the one 
> you have, then the lazyload() option is associated with the Group and it will 
> lazy load every time for the lifespan of that object.
> 
> I'm not sure yet why the lazyload() is somehow taking effect for the first 
> group.users in your example, though. it's not supposed to.
> 
> 
> 
> On Wed, Sep 25, 2019, at 1:07 PM, Marat Sharafutdinov wrote:
>> from sqlalchemy import Column, ForeignKey, Integer, create_engine
>> from sqlalchemy.ext.declarative import declarative_base
>> from sqlalchemy.orm import lazyload, relationship, sessionmaker
>> 
>> Base = declarative_base()
>> 
>> 
>> class Group(Base):
>>  __tablename__ = 'groups'
>> 
>>  id = Column(Integer, primary_key=True)
>> 
>>  users = relationship('User', lazy='raise')
>> 
>> 
>> class User(Base):
>>  __tablename__ = 'users'
>> 
>>  id = Column(Integer, primary_key=True)
>>  group_id = Column(Integer, ForeignKey('groups.id'))
>> 
>> 
>> engine = create_engine('sqlite:///:memory:', echo=True)
>> Base.metadata.create_all(engine)
>> 
>> Session = sessionmaker(bind=engine)
>> session = Session()
>> 
>> group = Group()
>> session.add(group)
>> session.commit()
>> 
>> group = session.query(Group).options(lazyload(Group.users)).first()
>> print('SUCCESS', group.users)
>> session.refresh(group)
>> print('FAILURE', group.users)
>> 
>> Is `session.expire(group)` is the only way to reload collections and related 
>> items?
>> 

>> --
>> 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/43ce8eb9-367d-43da-a371-0fa5e157e0de%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/sqlalchemy/43ce8eb9-367d-43da-a371-0fa5e157e0de%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/d8864771-f2ec-48d4-a5fe-e7798926666e%40www.fastmail.com
>  
> <https://groups.google.com/d/msgid/sqlalchemy/d8864771-f2ec-48d4-a5fe-e7798926666e%40www.fastmail.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/ba781a08-31ff-496a-afdf-adb37ba90841%40www.fastmail.com.

Reply via email to