You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hey guys, my team may have found a bug in get_scopefunc and we need confirmation.
For context, we're trying to get our test environment to mimic prod as close as possible.
However, there is an unexpected behaviour when using db.session inside a with app.app_context() block.
Naively, we'd expect that a new session would have been pushed inside the new context, as the session is allegedly nested inside and belongs to the app context, so a new app context should mean a new session. However, this is not what we found, and even after context switch, the same session is still in use.
I've pushed a minimal reproducible example here with instructions.
We think the problem lies in the get_scopefunc implementation for newer flask, where instead of having to use the flask-sqlalchemy's original_scopefunc and return an id: int, it actually returns a greenlet instance:
defget_scopefunc(original_scopefunc=None):
"""Returns :func:`.SessionScope`-aware `scopefunc` that has to be used during testing. """iforiginal_scopefuncisNone:
assertflask_sqlalchemy, 'Is Flask-SQLAlchemy installed?'try:
# for flask_sqlalchemy older than 2.2 where the connection_stack# was either the app stack or the request stackoriginal_scopefunc=flask_sqlalchemy.connection_stack.__ident_func__exceptAttributeError:
try:
# when flask_sqlalchemy 2.2 or newer, which supports only flask 0.10# or newer, we use app stackfromflaskimport_app_ctx_stackoriginal_scopefunc=_app_ctx_stack.__ident_func__exceptAttributeError:
# newer flask does not expose an __ident_func__, use greenlet directlyimportgreenlet# Should this be `original_scopefunc = lambda: id(greenlet.getcurrent)` or something alike?original_scopefunc=greenlet.getcurrentdefscopefunc():
rv=original_scopefunc()
sqlalchemy_scope=_session_scope_stack.topifsqlalchemy_scope:
rv= (rv, id(sqlalchemy_scope))
returnrvreturnscopefunc
We're not 100% sure, mainly because when passing the flask_sqlalchemy's implementation for scopefunc to original_scopefunc param, the tests run as expected (check tests/test_flask_sqlalchemy_get_scopefunc.py in the MRE repo), but when passing what we think would be the correct implementation to the greenlet path, the test still fails (check tests/test_greenlet_get_scopefunc.py in the MRE repo).
It would be great to have at least confirmation that this is the real problem, if possible.
I'm aware this explanation is not top notch, but I'm available for helping with whatever is needed here. Hopefully there is enough context for you guys to understand it. 😅
Thanks for the great module, BTW. 😄
Cheers!
The text was updated successfully, but these errors were encountered:
Hey guys, my team may have found a bug in
get_scopefunc
and we need confirmation.For context, we're trying to get our test environment to mimic prod as close as possible.
However, there is an unexpected behaviour when using
db.session
inside awith app.app_context()
block.Naively, we'd expect that a new session would have been pushed inside the new context, as the session is allegedly nested inside and belongs to the app context, so a new app context should mean a new session. However, this is not what we found, and even after context switch, the same session is still in use.
I've pushed a minimal reproducible example here with instructions.
We think the problem lies in the
get_scopefunc
implementation for newer flask, where instead of having to use the flask-sqlalchemy'soriginal_scopefunc
and return anid: int
, it actually returns agreenlet
instance:We're not 100% sure, mainly because when passing the
flask_sqlalchemy
's implementation forscopefunc
tooriginal_scopefunc
param, the tests run as expected (checktests/test_flask_sqlalchemy_get_scopefunc.py
in the MRE repo), but when passing what we think would be the correct implementation to the greenlet path, the test still fails (checktests/test_greenlet_get_scopefunc.py
in the MRE repo).It would be great to have at least confirmation that this is the real problem, if possible.
I'm aware this explanation is not top notch, but I'm available for helping with whatever is needed here. Hopefully there is enough context for you guys to understand it. 😅
Thanks for the great module, BTW. 😄
Cheers!
The text was updated successfully, but these errors were encountered: