Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to delete records from many-to-many (secondary) table in SQLAlchemy?

Tags:

I am having problems deleting records from PostTag table that contains Post and Tag column. This is my relation table:

tags = db.Table('PostTag',     db.Column('Tag', db.Integer, db.ForeignKey('Tag.Id')),     db.Column('Post', db.Integer, db.ForeignKey('Post.Id')) ) 

and

tags = db.relationship(Tag, secondary=tags, backref=db.backref('Post', lazy='dynamic')) 

When I do this:

from models.Post import Post  posts = Post.query.join(Post.tags).filter(Post.Id == id).all() if(posts):    return posts return False 

and then

for posttag in post[0].tags:     db.session.delete(posttag)     db.session.flush() 

Rows from many-to-many relation are deleted but also records from Tag table.

I just need to delete records from PostTag table for some condition (Post=1 for example)

I searched the internet but I did not find anything conclusive. I do not need cascade on many-to-many relationship.

This is sql log:

 297 Query  DELETE FROM `PostTag` WHERE `PostTag`.`Tag` = 14 AND `PostTag`.`Post` = 3  297 Query  DELETE FROM `PostTag` WHERE `PostTag`.`Tag` = 14 AND `PostTag`.`Post` = 18  297 Query  DELETE FROM `Tag` WHERE `Tag`.`Id` = 14 

Last row 297 Query DELETE FROMTagWHERETag.Id= 14 should not be there.

UPDATE / maybe solution

I kind of solved this with:

sql = 'DELETE FROM PostTag WHERE Post=%s' db.engine.execute(sql, post, ()) 

But that is not just ORM way. Same goes for insert. I will try to get this resolved ORM way. I will post answer if I make this problem go away.

like image 923
pregmatch Avatar asked Nov 15 '14 17:11

pregmatch


People also ask

How do I delete multiple rows in a Flask SQLAlchemy?

Delete multiple rows in SQLAlchemyGet the books table from the Metadata object initialized while connecting to the database. Pass the delete query to the execute() function and get all the results using fetchall() function. Use a for loop to iterate through the results.

How do I delete records in Flask SQLAlchemy?

To delete a record by id in Python Flask-SQLAlchemy, we can call the session delete method. to call session. delete to mark obj1 and obj2 to be deleted. And then we call session.

How do you create a many to many relationship in SQLAlchemy?

Python Flask and SQLAlchemy ORM Many to Many relationship between two tables is achieved by adding an association table such that it has two foreign keys - one from each table's primary key.


1 Answers

Try this:

post = db.session.query(Post).get(1) post.tags = [] db.session.commit() 

Here we are redefining the collection post.tags to the empty array and committing the changes. To explain this I'll refer to the SQLAlchemy docs:

Collections in SQLAlchemy are transparently instrumented. Instrumentation means that normal operations on the collection are tracked and result in changes being written to the database at flush time.

So SQLAlchemy keeps track of the changes we make to the collection post.tags and updates it on commit.

If we had only one tag (say sometag) we could use the remove method like this:

post = db.session.query(Post).get(1) post.tags.remove(sometag) db.session.commit() 
like image 178
pspencer Avatar answered Sep 18 '22 19:09

pspencer