2013-10-08 7 views
11

Il modello User ha una relazione con il modello Address. Ho specificato che la relazione dovrebbe sovrapporre l'operazione di cancellazione. Tuttavia, quando interrogo ed elimini un utente, ottengo un errore nel fatto che la riga di indirizzo è ancora referenziata. Come posso cancellare l'utente e gli indirizzi?SQLAlchemy: eliminazione non in cascata

class User(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    addresses = db.relationship('Address', cascade='all,delete', backref='user') 

class Address(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    user_id = db.Column(db.Integer, db.ForeignKey(User.id)) 
db.session.query(User).filter(User.my_id==1).delete() 
IntegrityError: (IntegrityError) update or delete on table "user" violates foreign key constraint "addresses_user_id_fkey" on table "address" 
DETAIL: Key (my_id)=(1) is still referenced from table "address". 
'DELETE FROM "user" WHERE "user".id = %(id_1)s' {'id_1': 1} 

risposta

27

si hanno le seguenti ...

db.session.query(User).filter(User.my_id==1).delete() 

noti che dopo "filtro", si sta ancora restituito un oggetto Query. Pertanto, quando si chiama delete(), si sta chiamando delete() sull'oggetto Query (non sull'oggetto Utente). Questo significa che si sta facendo un grosso delete (anche se probabilmente con solo una singola riga di essere eliminati)

Il metodo documentation for the Query.delete() che si sta utilizzando dice ...

Il metodo non offre in Python a cascata di relazioni - è presupponendo che ON DELETE CASCADE/SET NULL/etc. è configurato per qualsiasi riferimento a chiave esterna che lo richiede, altrimenti il ​​database può emettere una violazione di integrità se i riferimenti alle chiavi esterne vengono applicati a .

Come si dice, l'esecuzione dell'eliminazione in questo modo ignorerà le regole della cascata Python che hai impostato. Probabilmente voleva fare qualcosa di simile ..

user = db.session.query(User).filter(User.my_id==1).first() 
db.session.delete(user) 

In caso contrario, si potrebbe desiderare di guardare setting up the cascade for your database as well.

+0

Grazie mille segno. Perché il primo metodo funzioni, quali cambiamenti dovrei fare? – AndroidDev

+0

@BadLuckBrian: dipende dal database che si sta utilizzando. Leggi la documentazione a cui mi sono collegato alla fine della mia domanda per maggiori informazioni. Inoltre, leggi la documentazione per il tuo database. –

+0

Sto usando la posta su Heroku. Ho aggiunto l'opzione cascade alla colonna Chiave Foregien nelle tabelle degli indirizzi. Forse Flask-Migrate potrebbe non aver notato che questo vincolo è stato aggiunto? Potrebbe essere stato possibile? – AndroidDev