Skip to content
Snippets Groups Projects
Commit 88f54ded authored by Benjamin Bertrand's avatar Benjamin Bertrand
Browse files

Fix model update in admin interface

Following exception is raised when trying to update a network from
flask-admin:
sqlalchemy.exc.InvalidRequestError: Can't attach instance <User at 0x7f6f0e39ce10>;
another instance with key (<class 'app.models.User'>, (1,), None) is already present in this session.

1. If we remove the caching of the load_user method, the problem
disappears.
2. When updating a Network, this trigger an inventory update in
before_flush which adds a task to the session. This is when the
current_user is added to the session and the error raised.

So the problem is linked to the user caching and flask-admin.

The workaround is to remove the user object added by flask-admin to the
session.

JIRA INFRA-908 #action In Progress
parent 5b55f0ef
No related branches found
No related tags found
No related merge requests found
...@@ -14,6 +14,7 @@ from flask_admin.contrib import sqla ...@@ -14,6 +14,7 @@ from flask_admin.contrib import sqla
from flask_admin.model.form import converts from flask_admin.model.form import converts
from flask_login import current_user from flask_login import current_user
from ..validators import IPNetwork, ICS_ID_RE from ..validators import IPNetwork, ICS_ID_RE
from .. import models
# Monkey patch flask-admin Unique validator to disable it # Monkey patch flask-admin Unique validator to disable it
...@@ -47,6 +48,16 @@ class AdminModelView(sqla.ModelView): ...@@ -47,6 +48,16 @@ class AdminModelView(sqla.ModelView):
def is_accessible(self): def is_accessible(self):
return current_user.is_authenticated and current_user.is_admin return current_user.is_authenticated and current_user.is_admin
def update_model(self, form, model):
# Remove the current user object added by flask-admin from the session
# Adding the current_user object later raises an exception otherwise:
# sqlalchemy.exc.InvalidRequestError: Can't attach instance <User at 0x7f6f0e39ce10>;
# another instance with key (<class 'app.models.User'>, (1,), None) is already present in this session.
for obj in self.session:
if isinstance(obj, models.User) and obj.id == current_user.id:
self.session.expunge(obj)
return super().update_model(form, model)
class UserAdmin(AdminModelView): class UserAdmin(AdminModelView):
can_create = False can_create = False
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment