Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove all items from many-to-many collection in SqlAlchemy?

when I need to remove an object from declarative ORM many-to-many relationship, I am supposed to do this:

blogpost.tags.remove(tag)

Well. What am I supposed to do if I need to purge all these relations (not only one)? Typical situation: I'd like to set a new list of tags to my blogpost. So I need to...:

  1. Remove all existing relations between that blogpost and tags.
  2. Set new relations and create new tags if they don't exist.

Of course, there could be a better way of doing this. In that case please let me know.

like image 581
Honza Javorek Avatar asked Oct 25 '11 11:10

Honza Javorek


People also ask

What is all () in SQLAlchemy?

add a mapped entity to the list of result columns to be returned. method sqlalchemy.orm.Query. all() Return the results represented by this Query as a list. This results in an execution of the underlying SQL statement.

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.

What is session flush in SQLAlchemy?

session. flush() communicates a series of operations to the database (insert, update, delete). The database maintains them as pending operations in a transaction.

What is _sa_instance_state in SQLAlchemy?

_sa_instance_state is a non-database-persisted value used by SQLAlchemy internally (it refers to the InstanceState for the instance. While not directly relevant to this section, if we want to get at it, we should use the inspect() function to access it).


2 Answers

This is the standard Python idiom for clearing a list – assigning to the “entire list” slice:

blogpost.tags[:] = []

Instead of the empty list, you may want assign the new set of tags directly.

blogpost.tags[:] = new_tags

SQLAlchemy's relations are instrumented attributes, meaning that they keep the interface of a list (or set, dict, etc), but any changes are reflected in the database. This means that anything you can do with a list is possible with a relation, while SQLA transparently listens to the changes and updates the database accordingly.

like image 76
Petr Viktorin Avatar answered Oct 01 '22 19:10

Petr Viktorin


Confrimed for what Two-Bit Alchemist has reported.

blogpost.tags[:] = new_tags

will complain about

TypeError: 'AppenderBaseQuery' object does not support item assignment

But

blogpost.tags = new_tags

seems to work fine.

like image 35
Xuan Hu Avatar answered Oct 01 '22 19:10

Xuan Hu