1

I have query selecting list of users from the database. Every user object has list of tags. This is set in the Tag model using this relationship:

users = db.relationship('User', secondary=user_tag, backref=db.backref('tags', lazy='dynamic'), lazy='dynamic')

When the result from the query is returned I have user object:

id {int}1

tags {AppenderBaseQuery}(Select ...)

All good, but I want to assign new list to the tags property

user.tags=list()

but this row doesn't have any effect on the object and the user still contains the AppenderBaseQuery. How this property became immutable. I don't get it. Still new to python , sorry if the question is stupid.

EDIT:

I don't wont to change the database. I have tried to detach the user object from the session without success. I have the tags list already and just want to set it to the user object tags list. After I just serialize it to json and return response with list of users. Usualy I create for tags url, with url_for, but this time I want to return the tags lists with user to make the things faster

1 Answer 1

7

It is not immutable, but it is a bit special. You've configured your relationship and its backref using lazy='dynamic'. This makes it so that in place of an instrumented collection you have a Query object – handy for handling large collections of related objects. This query object has a few added methods and features in addition to the basic filter(), all() etc. of a query, such as append(), remove(), and support for assignment, but basically it's a shortcut for querying related objects. Reading the docs further we find:

Since the read side of the dynamic relationship always queries the database, changes to the underlying collection will not be visible until the data has been flushed. However, as long as “autoflush” is enabled on the Session in use, this will occur automatically each time the collection is about to emit a query.

If you've configured your engine to echo the SQL it sends, you should observe what happens when you do

user.tags = []
print user.tags.all()

Autoflush should kick in, updating all the originally related objects, nulling their foreign keys (depends on cascades) before the SELECT for fetching the relation is issued.

Sign up to request clarification or add additional context in comments.

4 Comments

I don't wont to change the database. I have tried to detach the user object from the session without success. I have the tags list already and just want to set it to the user object tags list. After I just serialize it to json and return response with list of users. Usualy I create for tags url, with url_for, but this time I want to return the tags lists with user to make the things faster
In that case I'd recommend setting the tags during serialization. As you've noticed the appender query attribute is for handling the relationship, i.e. data located in the DB. If I understood you correctly you have a separate set of tags belonging to users, so in my mind your best bet is to amalgamate them during serialization, not try and set them on the user objects first. But that's just an opinion.
Also you should include that in your question. As it is now it is a bit of an XY problem: you ask about something else instead of asking about what you're really trying to do, in this case add extra data to serialization of DB objects.
Yes. Thank you for your answer. I'm going to use that approach. I accepted your answer. What was really helpful is your comment. Regards

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.