2010-08-14 15 views
7

Je rencontre des problèmes avec la suppression de lignes d'une base de données et l'ajout de nouvelles. Voici le code:SQLAlchemy - ObjectDeletedError: l'instance '<Class at...>' a été supprimée. Aide

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() 

Fondamentalement, je lingette tous les utilisateurs des données de la table, puis ajouter dans leurs nouvelles options. Le problème est, le code produit cette erreur:

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

Je ne sais pas pourquoi ... D'après ce que mes recherches Google ont mis en place, l'erreur est produite parce que je suis modifier la classe Responsabilités après avoir supprimé tous ce sont les données de la base de données. Je n'arrive pas à comprendre comment 'laisser aller' de la classe pour la réinitialiser avec les nouvelles données.

Qu'est-ce que je fais mal?

EDIT

est ici la classe de responsabilité:

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) 

Et voici le retraçage:

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. 
+0

Pourriez-vous montrer aussi '' __init__' de dbmyaccount.Responsibilities' et dire quelle ligne déclenche une exception? –

+0

Mettre à jour mon message original avec l'information que vous avez demandé – dave

+0

Toujours ne peut pas reproduire cette erreur ici, votre code fonctionne très bien dans mes tests. Quelle version de SA utilisez-vous? –

Répondre

2

Le code que vous essayez d'exécuter est valide et je suppose que la faute se trouve à la configuration de votre mappeur, en particulier, votre relation utilisateur-responsabilités. Ce que vous devez faire est de définir la bonne cascade propriété de cette relation, vous devriez être en mesure de trouver le bon réglage pour votre schéma db, en suivant les directives données ici [l'élément cascade]: http://www.sqlalchemy.org/docs/orm/relationships.html#the-relationship-api

3

Lorsque vous effectuez une suppression groupée, elle supprime les lignes des bases de données mais ne met pas à jour les références aux objets en mémoire de la session SQLAlchemy. Vous pouvez utiliser l'argument synchronize_session à .delete() pour l'obtenir pour synchroniser la session:

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

Voir l'avertissement dans la documentation: http://docs.sqlalchemy.org/en/rel_1_0/orm/query.html?highlight=query.delete#sqlalchemy.orm.query.Query.delete