On Tue, Apr 5, 2022, at 3:09 PM, Thorsten von Stein wrote: > 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?
the scoped_session doesn't call "sessionmaker" repeatedly; it calls it once per thread, until you say scoped_session.remove(). it's a thread local registry for a persistent Session object. I do prefer passing sessions around as global registries tend to be forgotten and contribute to the "implicitness" of a program. > > 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 sqlalchemy+...@googlegroups.com. >>> 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 sqlalchemy+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/sqlalchemy/c03b1fe8-90f4-4192-a846-0d8ba136588an%40googlegroups.com > > <https://groups.google.com/d/msgid/sqlalchemy/c03b1fe8-90f4-4192-a846-0d8ba136588an%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/36452af7-b775-42b7-b2ec-541173adc590%40www.fastmail.com.