Bug description
I have a exception, when migrate to 4.0.0rc2 version:
superset_init | sqlalchemy.orm.exc.FlushError: Can't flush None value found in collection Role.permissions
i think that mistake here:
https://github.com/apache/superset/blob/master/superset/migrations/versions/2024-02-07_17-13_87d38ad83218_migrate_can_view_and_drill_permission.py#L41
may be replace it from:
NEW_PVMS = {"Dashboard": ("can_view_chart_as_table",)}
to:
NEW_PVMS = {"Dashboard": ("can_view_chart_as_table",), Pvm("Dashboard", "can_view_query")}
?
How to reproduce the bug
Migrate to 4.0.0rc2
Screenshots/recordings

Superset version
master / latest-dev
Python version
3.10
Node version
16
Browser
Chrome
Additional context
superset_init | INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
superset_init | INFO [alembic.runtime.migration] Will assume transactional DDL.
superset_init | INFO [alembic.runtime.migration] Running upgrade 1cf8e4344e2b -> 87d38ad83218, Migrate can_view_and_drill permission
superset_init | Removing can_view_and_drill Dashboard from Admin
superset_init | INFO [superset.migrations.shared.security_converge] Removing can_view_and_drill Dashboard from Admin
superset_init | Add can_view_chart_as_table Dashboard to Admin
superset_init | INFO [superset.migrations.shared.security_converge] Add can_view_chart_as_table Dashboard to Admin
superset_init | Add None to Admin
superset_init | INFO [superset.migrations.shared.security_converge] Add None to Admin
superset_init | Removing can_view_and_drill Dashboard from Alpha
superset_init | INFO [superset.migrations.shared.security_converge] Removing can_view_and_drill Dashboard from Alpha
superset_init | Add can_view_chart_as_table Dashboard to Alpha
superset_init | INFO [superset.migrations.shared.security_converge] Add can_view_chart_as_table Dashboard to Alpha
superset_init | Add None to Alpha
superset_init | INFO [superset.migrations.shared.security_converge] Add None to Alpha
superset_init | Removing can_view_and_drill Dashboard from Gamma
superset_init | INFO [superset.migrations.shared.security_converge] Removing can_view_and_drill Dashboard from Gamma
superset_init | Add can_view_chart_as_table Dashboard to Gamma
superset_init | INFO [superset.migrations.shared.security_converge] Add can_view_chart_as_table Dashboard to Gamma
superset_init | Add None to Gamma
superset_init | INFO [superset.migrations.shared.security_converge] Add None to Gamma
superset_init | Going to delete pvm: can_view_and_drill Dashboard
superset_init | INFO [superset.migrations.shared.security_converge] Going to delete pvm: can_view_and_drill Dashboard
superset_init | Loaded your LOCAL configuration at [/app/docker/pythonpath_dev/superset_config.py]
superset_init | Traceback (most recent call last):
superset_init | File "/usr/local/bin/superset", line 33, in
superset_init | sys.exit(load_entry_point('apache-superset', 'console_scripts', 'superset')())
superset_init | File "/usr/local/lib/python3.9/site-packages/click/core.py", line 1130, in call
superset_init | return self.main(*args, **kwargs)
superset_init | File "/usr/local/lib/python3.9/site-packages/click/core.py", line 1055, in main
superset_init | rv = self.invoke(ctx)
superset_init | File "/usr/local/lib/python3.9/site-packages/click/core.py", line 1657, in invoke
superset_init | return _process_result(sub_ctx.command.invoke(sub_ctx))
superset_init | File "/usr/local/lib/python3.9/site-packages/click/core.py", line 1657, in invoke
superset_init | return _process_result(sub_ctx.command.invoke(sub_ctx))
superset_init | File "/usr/local/lib/python3.9/site-packages/click/core.py", line 1404, in invoke
superset_init | return ctx.invoke(self.callback, **ctx.params)
superset_init | File "/usr/local/lib/python3.9/site-packages/click/core.py", line 760, in invoke
superset_init | return __callback(*args, **kwargs)
superset_init | File "/usr/local/lib/python3.9/site-packages/click/decorators.py", line 26, in new_func
superset_init | return f(get_current_context(), *args, **kwargs)
superset_init | File "/usr/local/lib/python3.9/site-packages/flask/cli.py", line 357, in decorator
superset_init | return __ctx.invoke(f, *args, **kwargs)
superset_init | File "/usr/local/lib/python3.9/site-packages/click/core.py", line 760, in invoke
superset_init | return __callback(*args, **kwargs)
superset_init | File "/usr/local/lib/python3.9/site-packages/flask_migrate/cli.py", line 149, in upgrade
superset_init | _upgrade(directory, revision, sql, tag, x_arg)
superset_init | File "/usr/local/lib/python3.9/site-packages/flask_migrate/init.py", line 98, in wrapped
superset_init | f(*args, **kwargs)
superset_init | File "/usr/local/lib/python3.9/site-packages/flask_migrate/init.py", line 185, in upgrade
superset_init | command.upgrade(config, revision, sql=sql, tag=tag)
superset_init | File "/usr/local/lib/python3.9/site-packages/alembic/command.py", line 294, in upgrade
superset_init | script.run_env()
superset_init | File "/usr/local/lib/python3.9/site-packages/alembic/script/base.py", line 490, in run_env
superset_init | util.load_python_file(self.dir, "env.py")
superset_init | File "/usr/local/lib/python3.9/site-packages/alembic/util/pyfiles.py", line 97, in load_python_file
superset_init | module = load_module_py(module_id, path)
superset_init | File "/usr/local/lib/python3.9/site-packages/alembic/util/compat.py", line 184, in load_module_py
superset_init | spec.loader.exec_module(module)
superset_init | File "", line 850, in exec_module
superset_init | File "", line 228, in _call_with_frames_removed
superset_init | File "/app/superset/extensions/../migrations/env.py", line 127, in
superset_init | run_migrations_online()
superset_init | File "/app/superset/extensions/../migrations/env.py", line 119, in run_migrations_online
superset_init | context.run_migrations()
superset_init | File "", line 8, in run_migrations
superset_init | File "/usr/local/lib/python3.9/site-packages/alembic/runtime/environment.py", line 813, in run_migrations
superset_init | self.get_context().run_migrations(**kw)
superset_init | File "/usr/local/lib/python3.9/site-packages/alembic/runtime/migration.py", line 561, in run_migrations
superset_init | step.migration_fn(**kw)
superset_init | File "/app/superset/migrations/versions/2024-02-07_17-13_87d38ad83218_migrate_can_view_and_drill_permission.py", line 65, in upgrade
superset_init | do_upgrade(session)
superset_init | File "/app/superset/migrations/versions/2024-02-07_17-13_87d38ad83218_migrate_can_view_and_drill_permission.py", line 53, in do_upgrade
superset_init | migrate_roles(session, PVM_MAP)
superset_init | File "/app/superset/migrations/shared/security_converge.py", line 248, in migrate_roles
superset_init | _delete_old_permissions(session, pvm_map)
superset_init | File "/app/superset/migrations/shared/security_converge.py", line 197, in _delete_old_permissions
superset_init | pvms_with_permission = (
superset_init | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/query.py", line 2819, in first
superset_init | return self.limit(1)._iter().first()
superset_init | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/query.py", line 2903, in _iter
superset_init | result = self.session.execute(
superset_init | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 1644, in execute
superset_init | ) = compile_state_cls.orm_pre_session_exec(
superset_init | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/context.py", line 319, in orm_pre_session_exec
superset_init | session._autoflush()
superset_init | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 2230, in _autoflush
superset_init | self.flush()
superset_init | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3367, in flush
superset_init | self._flush(objects)
superset_init | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3507, in flush
superset_init | transaction.rollback(capture_exception=True)
superset_init | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py", line 70, in exit
superset_init | compat.raise(
superset_init | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/compat.py", line 207, in raise
superset_init | raise exception
superset_init | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3467, in _flush
superset_init | flush_context.execute()
superset_init | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/unitofwork.py", line 456, in execute
superset_init | rec.execute(self)
superset_init | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/unitofwork.py", line 579, in execute
superset_init | self.dependency_processor.process_saves(uow, states)
superset_init | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 1136, in process_saves
superset_init | if not self._synchronize(
superset_init | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 1252, in _synchronize
superset_init | self._verify_canload(child)
superset_init | File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 257, in _verify_canload
superset_init | raise exc.FlushError(
superset_init | sqlalchemy.orm.exc.FlushError: Can't flush None value found in collection Role.permissions
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.
I have the same issue, and this worked for me.
may be replace it from:
NEW_PVMS = {"Dashboard": ("can_view_chart_as_table",)}
to:
NEW_PVMS = {"Dashboard": ("can_view_chart_as_table",), Pvm("Dashboard", "can_view_query")}
Faced the same problem, fixed by:
NEW_PVMS = {"Dashboard": ("can_view_chart_as_table", "can_view_query",)}