On Wed, Oct 24, 2018 at 7:15 PM Jonathan Vanasco <[email protected]> wrote:
>
> A new suite of unittests shed light on what appears to be anti-pattern in an 
> application. I'm not sure how to address this one.
>
>
> The general flow of a particular web request is this:
>
>
> Phase 1- load some database objects for general verification
>
> Phase 2- loop through a handful of routines to create some items. each 
> routine is an isolated transaction - not a subtransaction
>
>
> so it looks like this...
>
>
> # Phase1
>  foo = dbSession.query(FOO).all()
>
> # Phase2
>  for i in (a, b, c):
>     bar = BAR()
>     dbSession.add(bar)
>     dbSession.commit()
>
>
>
>
> The problem occurs sporadically in Phase2, when the code attempts to address 
> a lazyloaded attribute of the `foo` loaded in Phase1, and I get the error
> exc.ResourceClosedError("This Connection is closed")

that's not normal unless you are holding a Connection around and
calling close() on it, have a stack trace ?  or is this inside an
event handler?

>
> Digging into the events API and tracking everything, it appears my connection 
> is returned to the pool and closed on every `commit`.

session.commit() you mean, yes this is normal if the Session is bound
just to an engine.    if you bind the Session to a specific Connection
then it will keep using the same connection.

>
> I'm roughly seeing the events happen like this (the order of where the 
> 'action' happens may be shifted up or down a line):
>
> Phase 1
>     connect
>     checkin
>     engine_connect
>
> Phase 2 Action
>     commit
>     reset
>     checkout
>     checkin
>     engine_connect
>
> Phase 2 Action
>     commit
>     reset
>     checkout
>     checkin
>     engine_connect

That seems strange ?    the order should be, checkout, engine_connect,
commit, reset, checkin,

here's a demo:

from sqlalchemy import create_engine
from sqlalchemy.orm import Session
from sqlalchemy import event
import mock

e = create_engine("sqlite://")


m1 = mock.Mock()

event.listen(e, "commit", m1.commit)
event.listen(e, "reset", m1.reset)
event.listen(e, "checkout", m1.checkout)
event.listen(e, "checkin", m1.checkin)
event.listen(e, "engine_connect", m1.engine_connect)

s = Session(e)
s.execute("select 1")
s.commit()

s.execute("select 1")
s.commit()


for c in m1.mock_calls:
    print(c[0])


output:

checkout
engine_connect
commit
reset
checkin
checkout
engine_connect
commit
reset
checkin




>
> Phase 2 Action
>     EXCEPTION
>

I don't see any cause for that EXCEPTION.    the Session keeps on
connecting as needed.

> Is there a way to ensure the session doesn't close/checkin the connection on 
> certain commits

bind the Session to a Connection, but all the other things you're
observing don't make any sense

> or is there a better strategy to deal with this anti-pattern -- perhaps 
> figuring out a way to update the object sessions/connections ?

update....what exactly?


>
> I only have a handful of situations where there are multiple transactions 
> like this - maybe 1% of the potential views.
>
> It does look like I have two problems here too:
>
> 1. The symptom/problem of not being able to load this data from a previous 
> transaction.
> 2. The underlying problem of losing a connection in a request, when I know I 
> want to keep it for immediate use again.
>
>
> --
> 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 post to this group, send email to [email protected].
> Visit this group at https://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.

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

Reply via email to