Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django model reload_from_db() vs. explicitly recalling from db

If I have an object retrieved from a model, for example:

obj = Foo.objects.first()

I know that if I want to reference this object later and make sure that it has the current values from the database, I can call:

obj.refresh_from_db()

My question is, is there any advantage to using the refresh_from_db() method over simply doing?:

obj = Foo.objects.get(id=obj.id)

As far as I know, the result will be the same. refresh_from_db() seems more explicit, but in some cases it means an extra line of code. Lets say I update the value field for obj and later want to test that it has been updated to False. Compare:

obj = Foo.objects.first()
assert obj.value is True
# value of foo obj is updated somewhere to False and I want to test below
obj.refresh_from_db()
assert obj.value is False

with this:

obj = Foo.objects.first()
assert obj.value is True
# value of foo obj is updated somewhere to False and I want to test below
assert Foo.objects.get(id=obj.id).value is False

I am not interested in a discussion of which of the two is more pythonic. Rather, I am wondering if one method has a practical advantage over the other in terms of resources, performance, etc. I have read this bit of documentation, but I was not able to ascertain from that whether there is an advantage to using reload_db(). Thank you!

like image 538
elethan Avatar asked Sep 12 '16 21:09

elethan


1 Answers

Django sources are usually relatively easy to follow. If we look at the refresh_from_db() implementation, at its core it is still using this same Foo.objects.get(id=obj.id) approach:

db_instance_qs = self.__class__._default_manager.using(db).filter(pk=self.pk)
...
db_instance_qs = db_instance_qs.only(*fields)
...
db_instance = db_instance_qs.get()

Only there are couple extra bells and whistles:

  • deferred fields are ignored
  • stale foreign key references are cleared (according to the comment explanation)

So for everyday usage it is safe to say that they are pretty much the same, use whatever you like.

like image 66
serg Avatar answered Oct 20 '22 00:10

serg