ITADN

signature for SignallingSession.get_bind() doesn't match SessionBase.get_bind()

#1381Closedorenleaffer-verkada 创建于 2025-01-10
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 条评论