Skip to content
This repository has been archived by the owner on Oct 22, 2019. It is now read-only.

Avoid touching the database in prepare() #321

Merged
merged 1 commit into from Jul 2, 2017
Merged

Avoid touching the database in prepare() #321

merged 1 commit into from Jul 2, 2017

Conversation

maiksprenger
Copy link
Contributor

Thanks for a lovely project! I hopefully have a small improvement to contribute.

Mommy makes a database call when calling prepare on a recipe with a sequence. Usually, our aim when using prepare is to avoid database queries as they're slow. I dug into the code to find out why this call gets made, and I think it's avoidable.

--

If I'm not mistaken, the intention of this bit of code is to store a backup copy of the given iterator while being able to iterate through it for this make() or prepare() call. We need to detect if this is the first run, so we check if any instances are present or if the dictionary is empty.

This causes a problem when using prepare(), because it still does a call to the database - something we usually don't want when using prepare(). If I'm not mistaken, we can safely switch the statement around, which avoids the call to the database.

To be honest, my gut feeling is that the call to m.objects.count() can be avoided all together - the existing logic should be sufficient. But I'm playing it safe here ;)

If I'm not mistaken, the intention of this bit of code is to store a backup copy of the given iterator while being able to iterate through it for this `make()` or `prepare()` call. We need to detect if this is the first run, so we check if any instances are present or if the dictionary is empty.

This causes a problem when using `prepare()`, because it still does a call to the database - something we usually don't want when using `prepare()`. If I'm not mistaken, we can safely switch the statement around, which avoids the call to the database.

To be honest, my gut feeling is that the call to `m.objects.count()` can be avoided all together - the existing logic should be sufficient. But I'm playing it safe here ;)
@maiksprenger
Copy link
Contributor Author

This PR is a copy of #320, but against development as requested. Happy to report the tests pass now :)

Copy link
Contributor

@codingjoe codingjoe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sweet! Thanks for digging into that. Its gonna be very helpful to create faster tests. 👍

@@ -45,7 +45,7 @@ def _mapping(self, new_attrs):
m = finder.get_model(self.model)
else:
m = self.model
if m.objects.count() == 0 or k not in self._iterator_backups:
if k not in self._iterator_backups or m.objects.count() == 0:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd leave a comment, to why the oder matters, or even better a test ;)

@vandersonmota
Copy link
Collaborator

Thanks @maikhoepfel
AFAIK _iterator_backups are used to handle sequences (https://model-mommy.readthedocs.io/en/latest/recipes.html?highlight=sequences#sequences-in-recipes)

But anyways, this is a nice addition, since the check in _iterator_backups will short circuit in case of being true.

@vandersonmota vandersonmota merged commit 1419b27 into berinhard:development Jul 2, 2017
@maiksprenger maiksprenger deleted the maikhoepfel-patch-2 branch July 4, 2017 16:30
@maiksprenger
Copy link
Contributor Author

maiksprenger commented Jul 4, 2017

Thanks for merging that! I added some tests locally that test for whether the database is touched, but unfortunately removing the call to m.objects.count() is not easily possible. So as it stands, prepare will still touch the database in some scenarios. I hope I'll get time to revisit this.
Nonetheless, this is an improvement :).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants