Thanks, Mike. Yes, I am using the scoped session. Am I understanding you 
correctly that, when using the scoped session, there is no penalty when 
calling the sessionmaker repeatedly, but that you still prefer passing 
around sessions as parameters for transparency reasons?

On Tuesday, April 5, 2022 at 11:58:33 AM UTC-7 Mike Bayer wrote:

>
>
> On Tue, Apr 5, 2022, at 1:02 PM, Thorsten von Stein wrote:
>
> I'm currently trying to get my applications ready for SQLAlchemy 2.0. A 
> change that has forces code changes in numerous places is the removal of 
> the automatic addition of new instances to the session upon establishing a 
> relationship with an object already in the session. In the explanation of 
> the change this is described "not generally a desirable behavior". However, 
> it is a behavior on which I currently completely rely for persisting new 
> instances. Since, in my system, new instances are always connected to a 
> parent object, I never had to add any object explicitly to a session, and 
> so session objects are currently basically absent from the application code.
>
> Here are my questions:
> - Will there be a way to turn back on this behavior in 2.0? I would be 
> thrilled if there was, but I fear the answer is negative.
>
>
> the whole behavior is done using event handlers which is public API.  so 
> you could set up the attributeevents.append() [1] and attributeevents.set() 
> [2] event handlers to add the local side to the session:
>
> from sqlalchemy import Column
> from sqlalchemy import create_engine
> from sqlalchemy import event
> from sqlalchemy import ForeignKey
> from sqlalchemy import Integer
> from sqlalchemy import String
> from sqlalchemy.orm import declarative_base
> from sqlalchemy.orm import object_session
> from sqlalchemy.orm import relationship
> from sqlalchemy.orm import Session
> from sqlalchemy.orm import configure_mappers
>
> Base = declarative_base()
>
>
> class A(Base):
>     __tablename__ = "a"
>
>     id = Column(Integer, primary_key=True)
>     data = Column(String)
>     bs = relationship("B", backref="a")
>
>
> class B(Base):
>     __tablename__ = "b"
>     id = Column(Integer, primary_key=True)
>     a_id = Column(ForeignKey("a.id"))
>     data = Column(String)
>
> configure_mappers()
>
> @event.listens_for(B.a, "set")
> def set_(target, newvalue, oldvalue, initiator):
>     sess = object_session(newvalue)
>     if target not in sess:
>         sess.add(target)
>
>
> e = create_engine("sqlite://", echo=True)
> Base.metadata.create_all(e)
>
> s = Session(e)
>
> a1 = A()
> s.add(a1)
> s.commit()
>
>
> b1 = B(a=a1)
> assert b1 in s.new
>
>
>
> [1] 
> https://docs.sqlalchemy.org/en/14/orm/events.html?highlight=attributeevents#sqlalchemy.orm.AttributeEvents.append
> [2] 
> https://docs.sqlalchemy.org/en/14/orm/events.html?highlight=attributeevents#sqlalchemy.orm.AttributeEvents.set
>
> there's an example of how to add new attribute events automatically at 
> https://docs.sqlalchemy.org/en/14/_modules/examples/custom_attributes/listen_for_events.html
>  
> , though you'd want to alter it to test each new attribute for being an 
> "object" based attribute.
>
>
> - How would you recommend dealing with the situation: Either passing 
> sessions as additional parameters to any function or method that creates 
> new objects, or, calling the session maker within each such function? In 
> particular, is there any particular downside to the latter?
>
>
>
> For a given chain of methods that are working in the same transaction I 
> would have a Session that's passed around to all of them, likely via some 
> contextual object, so that they can all ensure the object is added to the 
> persistence context as needed.      calling a sessionmaker inside of each 
> method implies you're building a new session/transaction inside of each 
> method which means each method would need to commit its own transaction, 
> did you mean the scoped_session()?  scoped_session is an option as well if 
> you are already using that, though I favor an explicit session/context 
> being passed around as this allows functions and methods to explicitly 
> state that they need to take place within this particular kind of context.
>
>
>
>
>
>
> -- 
> 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 [email protected].
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/sqlalchemy/792f9a59-2a9f-4dfb-82f0-82ef7f5e4328n%40googlegroups.com
>  
> <https://groups.google.com/d/msgid/sqlalchemy/792f9a59-2a9f-4dfb-82f0-82ef7f5e4328n%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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/c03b1fe8-90f4-4192-a846-0d8ba136588an%40googlegroups.com.

Reply via email to