Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLAlchemy - ObjectDeletedError: Instance '<Class at...>' has been deleted. Help

I'm having some issues with deleting rows from a database and then adding new ones. Here's the code:

for positionid in form_result['responsibilities']:
   inputdata = form_result['responsibilities'][positionid]

    self.__deleterow(dbmyaccount.Responsibilities, session['authed']['userid'])

    for resp in (i.strip() for i in inputdata.split(',')):
        resp_q = dbmyaccount.Responsibilities(session['authed']['userid'])

        resp_q.positionid     = positionid
        resp_q.responsibility = resp

        Session.add(resp_q)
        Session.commit()

def __deleterow(self, table, user):       
    delete_q = Session.query(table).filter_by(userid=user).first()

    if delete_q:
        Session.query(table).filter_by(userid=user).delete()
        Session.commit()

Basically, I wipe all the users data from the table then add in their new options. The problem is, the code produces this error:

ObjectDeletedError: Instance '<Responsibilities at ...>' has been deleted.

I have no idea why... From what my Google searches have turned up, the error is produced because I'm modifying the Responsibilities class after having deleted all it's data from the database. I can't figure out how to 'let go' of the class though to reinitialise it with the new data.

What am I doing wrong?

EDIT

Here's the Responsibility class:

class Responsibilities(Base):

__tablename__ = 'responsibilities'

id             = Column(Integer, primary_key=True)
userid         = Column(Integer, ForeignKey('users.id'))
positionid     = Column(Integer)
responsibility = Column(String(50))

def __init__(self, user=None):
    if user:
        self.userid = user

def __repr__(self):
    return "<Responsibilities({0})".format(self.userid)

And here's the traceback:

File '<string>', line 2 in save
File 'C:\\Users\\Dave\\Documents\\Python\\pylons\\mydevenv\\lib\\site-packages\\pylons-1.0-py2.6.egg\\pylons\\decorators\\rest.py', line 33 in check_methods
  return func(*args, **kwargs)
File 'C:\\Users\\Dave\\Documents\\Python\\pylons\\website\\website\\controllers\\myaccount.py', line 260 in save
  self.__deleterow(dbmyaccount.Responsibilities, session['authed']['userid'])
File 'C:\\Users\\Dave\\Documents\\Python\\pylons\\website\\website\\controllers\\myaccount.py', line 210 in __deleterow
  Session.query(table).filter_by(userid=user).delete()
File 'C:\\Users\\Dave\\Documents\\Python\\pylons\\mydevenv\\lib\\site-packages\\sqlalchemy-0.6.3-py2.6.egg\\sqlalchemy\\orm\\query.py', line 2031 in delete
  eval_condition(obj)]
File 'C:\\Users\\Dave\\Documents\\Python\\pylons\\mydevenv\\lib\\site-packages\\sqlalchemy-0.6.3-py2.6.egg\\sqlalchemy\\orm\\evaluator.py', line 82 in evaluate
  left_val = eval_left(obj)
File 'C:\\Users\\Dave\\Documents\\Python\\pylons\\mydevenv\\lib\\site-packages\\sqlalchemy-0.6.3-py2.6.egg\\sqlalchemy\\orm\\evaluator.py', line 42 in <lambda>
  return lambda obj: get_corresponding_attr(obj)
File 'C:\\Users\\Dave\\Documents\\Python\\pylons\\mydevenv\\lib\\site-packages\\sqlalchemy-0.6.3-py2.6.egg\\sqlalchemy\\orm\\attributes.py', line 163 in __get__
  instance_dict(instance))
File 'C:\\Users\\Dave\\Documents\\Python\\pylons\\mydevenv\\lib\\site-packages\\sqlalchemy-0.6.3-py2.6.egg\\sqlalchemy\\orm\\attributes.py', line 382 in get
  value = callable_(passive=passive)
File 'C:\\Users\\Dave\\Documents\\Python\\pylons\\mydevenv\\lib\\site-packages\\sqlalchemy-0.6.3-py2.6.egg\\sqlalchemy\\orm\\state.py', line 280 in __call__
  self.manager.deferred_scalar_loader(self, toload)
File 'C:\\Users\\Dave\\Documents\\Python\\pylons\\mydevenv\\lib\\site-packages\\sqlalchemy-0.6.3-py2.6.egg\\sqlalchemy\\orm\\mapper.py', line 2441 in _load_scalar_attributes
  state_str(state))
ObjectDeletedError: Instance '<Responsibilities at ...>' has been deleted.
like image 461
dave Avatar asked Aug 14 '10 04:08

dave


2 Answers

When you do a bulk delete, it deletes the rows from the databases but does not update references to the in-memory objects in the SQLAlchemy session. You can use the synchronize_session argument to .delete() to get it to sync the session:

Session.query(table).filter_by(userid=user).delete(synchronize_session='fetch')

See the warning in the docs: http://docs.sqlalchemy.org/en/rel_1_0/orm/query.html?highlight=query.delete#sqlalchemy.orm.query.Query.delete

like image 130
Zach Mathew Avatar answered Sep 24 '22 06:09

Zach Mathew


The code you're trying to execute is valid and I guess the fault lies at your mapper configuration, specifically, your User-Responsibilities relationship. What you should do is to set the proper cascade property for this relationship, you should be able to figure out the proper setting for your db schema, by following the guidelines given here [the cascade item]: http://www.sqlalchemy.org/docs/orm/relationships.html#the-relationship-api

like image 31
vonPetrushev Avatar answered Sep 20 '22 06:09

vonPetrushev