signature for SignallingSession.get_bind() doesn't match SessionBase.get_bind()
I'm writing code to use a cache in sqlalchemy and calling `orm_context.invoke_statement()` which fails with
```
SignallingSession.get_bind() got an unexpected keyword argument '_sa_skip_events'
```
sqlalchemy's invoke_statement() adds _sa_skip_events to the bind which breaks things. I believe it's because in flask sqlalchemy, SignallingSession has
```
def get_bind(self, mapper=None, clause=None):
```
While in sqlalchemy it is:
```
def get_bind(
self,
mapper=None,
clause=None,
bind=None,
_sa_skip_events=None,
_sa_skip_for_implicit_returning=False,
):
```
My workaround looks like this:
```
class CacheCompatibleSignallingSession(SignallingSession):
"""
sqlalchemy cache compatibility hack
sqlalchemy slips an argument named _sa_skip_events into the arguments to get_bind
when it calls it from invoke_statement() but it ignores the argument
"""
def get_bind(self, mapper=None, clause=None, **_kwargs):
return super().get_bind(mapper, clause)
class CacheCompatibleSQLAlchemy(SQLAlchemy):
"""See above"""
def create_session(self, options):
return sessionmaker(class_=CacheCompatibleSignallingSession, db=self, **options)
```
It's not clear to me if this is a bug in sqlalchemy or flask-sqlalchemy. It seems like the argument `_sa_skip_events` should have been consumed by sqlalchemy by popping it out of `bind_arguments` or flask-sqlalchemy should handle it. I'm filing this here because `get_bind` on the sqlalchemy side does handle the argument (though it doesn't seem to do anything with it).
https://github.com/sqlalchemy/sqlalchemy/blob/c9f8c5e5cd60892c1f14c9264c5acf775c9aa99d/lib/sqlalchemy/orm/session.py#L2697
To repro -
```
import flask
app = flask.Flask("app")
app.config["SQLALCHEMY_DATABASE_URI"] = <uri>
def _orm_execute_listener(orm_execute_state):
return orm_execute_state.invoke_statement()
from sqlalchemy import event
event.listen(Session, "do_orm_execute", _orm_execute_listener)
from flask_sqlalchemy import SQLAlchemy
database = SQLAlchemy(app)
# import some model type as Model
with database.session() as s: s.query(Model).first()
# TypeError: SignallingSession.get_bind() got an unexpected keyword argument '_sa_skip_events'
```
Environment:
- Python version: 3.10
- Flask-SQLAlchemy version: flask_sqlalchemy==2.5.1
- SQLAlchemy version: sqlalchemy==1.4.54
关闭于 2025-01-11 2 条评论