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 FROM
TagWHERE
Tag.
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.
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.
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.
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.
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With