SQLAlchemy sessions - DetachedInstanceError?
- by benjaminhkaiser
I have a function that attempts to take a list of usernames, look each one up in a user table, and then add them to a membership table. If even one username is invalid, I want the entire list to be rolled back, including any users that have already been processed. I thought that using sessions was the best way to do this but I'm running into a DetachedInstanceError:
DetachedInstanceError: Instance <Organization at 0x7fc35cb5df90> is not bound to a Session; attribute refresh operation cannot proceed
Full stack trace is here.
The error seems to trigger when I attempt to access the user (model) object that is returned by the query. From my reading I understand that it has something to do with there being multiple sessions, but none of the suggestions I saw on other threads worked for me. Code is below:
def add_members_in_bulk(organization_eid, users):
"""Add users to an organization in bulk - helper function for add_member()"""
"""Returns "success" on success and id of first failed student on failure"""
session = query_session.get_session()
session.begin_nested()
users = users.split('\n')
for u in users:
try:
user = user_lookup.by_student_id(u)
except ObjectNotFoundError:
session.rollback()
return u
if user:
membership.add_user_to_organization(
user.entity_id,
organization_eid,
'',
[]
)
session.flush()
session.commit()
return 'success'
here's the membership.add_user_to_organization:
def add_user_to_organization(user_eid, organization_eid, title, tag_ids):
"""Add a User to an Organization with the given title"""
user = user_lookup.by_eid(user_eid)
organization = organization_lookup.by_eid(organization_eid)
new_membership = OrganizationMembership(
organization_eid=organization.entity_id,
user_eid=user.entity_id,
title=title)
new_membership.tags = [get_tag_by_id(tag_id) for tag_id in tag_ids]
crud.add(new_membership)
and here is the lookup by ID query:
def by_student_id(student_id, include_disabled=False):
"""Get User by RIN"""
try:
return get_query_set(include_disabled).filter(User.student_id == student_id).one()
except NoResultFound:
raise ObjectNotFoundError("User with RIN %s does not exist." % student_id)