lohart13 opened a new issue, #32872: URL: https://github.com/apache/superset/issues/32872
### Bug description When the `SupersetSecurityManager.role_model` is overridden to use a custom role, any updates where the `SupersetSecurityManager.find_roles_by_id` function is called will cause an error as the update command is using the `flask_appbuilder.security.sqla.models.Role` model instead of the user supplied `SupersetSecurityManager.role_model`. Making the below changes to the `SupersetSecurityManager` fixes the issue. https://github.com/apache/superset/blob/50fe7483ae3f7fa02a476b9e5e384bd0031359d7/superset/security/manager.py#L1125-L1130 ```python def find_roles_by_id(self, role_ids: list[int]) -> list[Role]: """ Find a List of models by a list of ids, if defined applies `base_filter` """ query = self.get_session.query(self.role_model).filter(self.role_model.id.in_(role_ids)) return query.all() ``` ### Screenshots/recordings _No response_ ### Superset version master / latest-dev ### Python version 3.9 ### Node version 18 or greater ### Browser Chrome ### Additional context ``` superset | Attempting to flush an item of type <class 'flask_appbuilder.security.sqla.models.Role'> as a member of collection "Dashboard.roles". Expected an object of type <class 'models.CustomRole'> or a polymorphic subclass of this type. superset | Traceback (most recent call last): superset | File "/app/superset/daos/base.py", line 188, in update superset | db.session.merge(item) superset | File "<string>", line 2, in merge superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 2971, in merge superset | self._autoflush() superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 2230, in _autoflush superset | self.flush() superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3367, in flush superset | self._flush(objects) superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3507, in _flush superset | transaction.rollback(_capture_exception=True) superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py", line 70, in __exit__ superset | compat.raise_( superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/compat.py", line 207, in raise_ superset | raise exception superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3467, in _flush superset | flush_context.execute() superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/unitofwork.py", line 456, in execute superset | rec.execute(self) superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/unitofwork.py", line 579, in execute superset | self.dependency_processor.process_saves(uow, states) superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 1136, in process_saves superset | if not self._synchronize( superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 1252, in _synchronize superset | self._verify_canload(child) superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 283, in _verify_canload superset | raise exc.FlushError( superset | sqlalchemy.orm.exc.FlushError: Attempting to flush an item of type <class 'flask_appbuilder.security.sqla.models.Role'> as a member of collection "Dashboard.roles". Expected an object of type <class 'models.CustomRole'> or a polymorphic subclass of this type. superset | superset | The above exception was the direct cause of the following exception: superset | superset | Traceback (most recent call last): superset | File "/app/superset/commands/dashboard/update.py", line 54, in run superset | dashboard = DashboardDAO.update(self._model, self._properties, commit=False) superset | File "/app/superset/daos/base.py", line 194, in update superset | raise DAOUpdateFailedError(exception=ex) from ex superset | superset.daos.exceptions.DAOUpdateFailedError: Update failed superset | 2025-03-27 00:27:07,447:ERROR:superset.commands.dashboard.update:Attempting to flush an item of type <class 'flask_appbuilder.security.sqla.models.Role'> as a member of collection "Dashboard.roles". Expected an object of type <class 'models.CustomRole'> or a polymorphic subclass of this type. superset | Traceback (most recent call last): superset | File "/app/superset/daos/base.py", line 188, in update superset | db.session.merge(item) superset | File "<string>", line 2, in merge superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 2971, in merge superset | self._autoflush() superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 2230, in _autoflush superset | self.flush() superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3367, in flush superset | self._flush(objects) superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3507, in _flush superset | transaction.rollback(_capture_exception=True) superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py", line 70, in __exit__ superset | compat.raise_( superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/compat.py", line 207, in raise_ superset | raise exception superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3467, in _flush superset | flush_context.execute() superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/unitofwork.py", line 456, in execute superset | rec.execute(self) superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/unitofwork.py", line 579, in execute superset | self.dependency_processor.process_saves(uow, states) superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 1136, in process_saves superset | if not self._synchronize( superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 1252, in _synchronize superset | self._verify_canload(child) superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 283, in _verify_canload superset | raise exc.FlushError( superset | sqlalchemy.orm.exc.FlushError: Attempting to flush an item of type <class 'flask_appbuilder.security.sqla.models.Role'> as a member of collection "Dashboard.roles". Expected an object of type <class 'models.CustomRole'> or a polymorphic subclass of this type. superset | superset | The above exception was the direct cause of the following exception: superset | superset | Traceback (most recent call last): superset | File "/app/superset/commands/dashboard/update.py", line 54, in run superset | dashboard = DashboardDAO.update(self._model, self._properties, commit=False) superset | File "/app/superset/daos/base.py", line 194, in update superset | raise DAOUpdateFailedError(exception=ex) from ex superset | superset.daos.exceptions.DAOUpdateFailedError: Update failed superset | Error updating model DashboardRestApi: Dashboard could not be updated. superset | Traceback (most recent call last): superset | File "/app/superset/daos/base.py", line 188, in update superset | db.session.merge(item) superset | File "<string>", line 2, in merge superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 2971, in merge superset | self._autoflush() superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 2230, in _autoflush superset | self.flush() superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3367, in flush superset | self._flush(objects) superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3507, in _flush superset | transaction.rollback(_capture_exception=True) superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py", line 70, in __exit__ superset | compat.raise_( superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/compat.py", line 207, in raise_ superset | raise exception superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3467, in _flush superset | flush_context.execute() superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/unitofwork.py", line 456, in execute superset | rec.execute(self) superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/unitofwork.py", line 579, in execute superset | self.dependency_processor.process_saves(uow, states) superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 1136, in process_saves superset | if not self._synchronize( superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 1252, in _synchronize superset | self._verify_canload(child) superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 283, in _verify_canload superset | raise exc.FlushError( superset | sqlalchemy.orm.exc.FlushError: Attempting to flush an item of type <class 'flask_appbuilder.security.sqla.models.Role'> as a member of collection "Dashboard.roles". Expected an object of type <class 'models.CustomRole'> or a polymorphic subclass of this type. superset | superset | The above exception was the direct cause of the following exception: superset | superset | Traceback (most recent call last): superset | File "/app/superset/commands/dashboard/update.py", line 54, in run superset | dashboard = DashboardDAO.update(self._model, self._properties, commit=False) superset | File "/app/superset/daos/base.py", line 194, in update superset | raise DAOUpdateFailedError(exception=ex) from ex superset | superset.daos.exceptions.DAOUpdateFailedError: Update failed superset | superset | The above exception was the direct cause of the following exception: superset | superset | Traceback (most recent call last): superset | File "/app/superset/dashboards/api.py", line 566, in put superset | changed_model = UpdateDashboardCommand(pk, item).run() superset | File "/app/superset/commands/dashboard/update.py", line 64, in run superset | raise DashboardUpdateFailedError() from ex superset | superset.commands.dashboard.exceptions.DashboardUpdateFailedError: Dashboard could not be updated. superset | 2025-03-27 00:27:07,448:ERROR:superset.dashboards.api:Error updating model DashboardRestApi: Dashboard could not be updated. superset | Traceback (most recent call last): superset | File "/app/superset/daos/base.py", line 188, in update superset | db.session.merge(item) superset | File "<string>", line 2, in merge superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 2971, in merge superset | self._autoflush() superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 2230, in _autoflush superset | self.flush() superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3367, in flush superset | self._flush(objects) superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3507, in _flush superset | transaction.rollback(_capture_exception=True) superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py", line 70, in __exit__ superset | compat.raise_( superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/compat.py", line 207, in raise_ superset | raise exception superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3467, in _flush superset | flush_context.execute() superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/unitofwork.py", line 456, in execute superset | rec.execute(self) superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/unitofwork.py", line 579, in execute superset | self.dependency_processor.process_saves(uow, states) superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 1136, in process_saves superset | if not self._synchronize( superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 1252, in _synchronize superset | self._verify_canload(child) superset | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 283, in _verify_canload superset | raise exc.FlushError( superset | sqlalchemy.orm.exc.FlushError: Attempting to flush an item of type <class 'flask_appbuilder.security.sqla.models.Role'> as a member of collection "Dashboard.roles". Expected an object of type <class 'models.CustomRole'> or a polymorphic subclass of this type. superset | superset | The above exception was the direct cause of the following exception: superset | superset | Traceback (most recent call last): superset | File "/app/superset/commands/dashboard/update.py", line 54, in run superset | dashboard = DashboardDAO.update(self._model, self._properties, commit=False) superset | File "/app/superset/daos/base.py", line 194, in update superset | raise DAOUpdateFailedError(exception=ex) from ex superset | superset.daos.exceptions.DAOUpdateFailedError: Update failed superset | superset | The above exception was the direct cause of the following exception: superset | superset | Traceback (most recent call last): superset | File "/app/superset/dashboards/api.py", line 566, in put superset | changed_model = UpdateDashboardCommand(pk, item).run() superset | File "/app/superset/commands/dashboard/update.py", line 64, in run superset | raise DashboardUpdateFailedError() from ex superset | superset.commands.dashboard.exceptions.DashboardUpdateFailedError: Dashboard could not be updated. ### Checklist - [x] I have searched Superset docs and Slack and didn't find a solution to my problem. - [x] I have searched the GitHub issue tracker and didn't find a similar bug report. - [x] I have checked Superset's logs for errors and if I found a relevant Python stacktrace, I included it here as text in the "additional context" section. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: notifications-unsubscr...@superset.apache.org.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: notifications-unsubscr...@superset.apache.org For additional commands, e-mail: notifications-h...@superset.apache.org