ho la seguente configurazione SQLAlchemy:SQLAlchemy: Cancellare oggetto direttamente da uno-a-molti senza utilizzare Session.delete()
Base = declarative_base()
class Post(Base):
__tablename__ = 'post'
id = Column(Integer, primary_key=True)
title = Column(String(30))
comments = relationship('Comment', cascade='all')
class Comment(Base):
__tablename__ = 'comment'
id = Column(Integer, primary_key=True)
post_id = Column(Integer, ForeignKey(Post.id, ondelete='CASCADE'), nullable=False)
text = Column(Text)
Con questo, posso creare oggetti postali con un one-to molte relazioni con i commenti. Voglio gestire la creazione e la cancellazione dei commenti per i post senza fare riferimento alla sessione. L'aggiunta di un commento ad un post funziona bene:
post = Post(title='some post')
comment = Comment(text='some comment')
post.comments.append(comment)
mio gestore di sessione conosce solo i messaggi, quindi sarebbe fare un session.add(post)
e il commento viene inserito nella sessione automaticamente e viene sincronizzato con il database sul prossimo session.commit()
. Tuttavia, lo stesso non è vero per la cancellazione dei commenti. Voglio essere in grado di cancellare un commento da solo facendo:
post.comments.remove(comment)
Tuttavia, questo produce il seguente errore sul prossimo session.commit()
:
sqlalchemy.exc.OperationalError: (OperationalError) (1048, "Column 'post_id' cannot be null") 'UPDATE comment SET post_id=%s WHERE comment.id = %s' (None, 1L)
Come faccio a dire SQLAlchemy di non aggiornare il commento con un valore NULL
per post_id (che non è consentito a causa del vincolo non nullo sulla colonna), ma eliminare invece il commento? So che potrei fare session.delete(comment)
, ma poiché non ho bisogno di aggiungere il commento alla sessione in modo esplicito, non vedo un motivo per cui dovrei doverlo eliminare esplicitamente dalla sessione.
Ho trovato diverse soluzioni per le eliminazioni in cascata di oggetti correlati, ma poiché non ho mai pubblicato alcuna cancellazione esplicita per la sessione (il post è ancora lì), non penso che sia applicabile.
Modifica: ho modificato l'esempio per includere la sovrapposizione di cancellazioni dai post. Ora funziona per fare session.delete(post)
e tutti i commenti sono cancellati. Ma voglio solo cancellare automaticamente i commenti che ho rimosso dalla relazione e non eliminare l'intero post con tutti i commenti.
TL; DR: Come si comunica a SQLAlchemy di emettere un'istruzione di eliminazione anziché un'istruzione di aggiornamento quando rimuovo una voce da un elenco di relazioni di una relazione uno-a-molti?
Con l'opzione 'delete-orphan' nelle cascate, la cancellazione alla rimozione dall'elenco delle relazioni funziona come previsto. Grazie. – Varicus