On Jan 7, 2013, at 1:11 AM, Ken Lareau wrote: > > Okay, this is what I suspected and feared. :) Creating new sessions isn't > much of an > issue, and I came up with a class to manage this for me before realizing my > problem > is going to end up being much deeper... > > My current library that uses SQLAlchemy was based off a single session... so > in a > file called meta.py I had the following line: > > Session = scoped_session(sessionmaker()) > > (swiped from an old Pylons example). In my __init__.py file, I did: > > from tagopsdb.database.meta import Session > > and then in when initializing my connection to the database, simply did: > > Session.configure(bind=<engine>) > > From all other areas of the library, I simple re-used the aforementioned > import, then > actually directly used Session, such as: > > Session.add(<obj>) > > or > > Session.commit() > > Now... this may be very poor usage of it, though I'm trying to improve my > under- > standing and utilize SQLAlchemy better.
that's pretty much the usage we've encouraged for a long time, the "Session" is basically "the main Session", I think its OK. > Of course, with the sudden need for more > than one session, I'm finding that I'm running into an issue. Specifically: > > 1) To make it easy to find the correct session, I'm using a dictionary which I > pass around instead of Session... but referencing a given session is a bit > clunky - 'sessions.current[<name>]' is quite a bit less succinct than the > use of just 'Session', and while I could just assign a given entry to a > shorter > name, that just seems to add to the mistake. :) Depending on the usage pattern here, if the need for the "extra" transaction is localized, then I'd be using an explicit passing pattern for this second Session - that is, not using a global registry. If the case is more like large amounts of code are split 50/50 between these two Sessions, then I'd possibly use a second Session registry. Since this Session is more intended as an ad-hoc "commit" Session though I might stick to keeping it as a non-global object. > > 2) All the methods in my library currently expect the session to be 'Session'; > that changes with the need for multiple sessions, and it means either I > will now need to explicitly pass the session into every method, or find a > way to have the session automatically determined... which may not be > possible or reasonable. OK, well there's another path here, which is that you can affix a second Session object to your registry temporarily. existing = Session.registry() # current Session Session.registry.set(my_temporary_session) # set a different Session ... call functions ... # restore the original Session.registry.set(existing) > > Depending on the database in use, using low isolation levels can have the > effect that other transactions can view "dirty reads" as the transaction > proceeds, but this is obviously an all-or-nothing thing. When I need > certain resources exposed during a long running transaction, I transfer that > data to a different Session and commit() those changes distinctly. > > My current needs would tend to use the short transactions for things that are > mostly > isolated from anything going on in the longer running (main) transaction, > though I do > suspect I might need what you mention in your last sentence, but might you be > able > to refer me to an example of how it would work, perchance? I'd advise against going this route, you'd pretty much need to use MySQL MyISAM tables to get guaranteed "dirty reads", that is, there's no transaction at all, and it's not really how transactions were meant to be used. Lowering the isolation level is usually just a means to get more transaction throughput. -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
