Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#2114 repeating query in django view #2158

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

Pokapiec
Copy link

What does this pull request do?

In this PR i add another condition to elif statement in utils.encoding.transform function to handle displaying representation of django QuerySet object in custom way. We need to do it because if we try to execute repr function on unexecuted QuerySet which causes Timeout on database, it will execute by utils.encoding.transform function.

I also added a simple test simulating database Timeout.

By overwriting _result_cache on django QuerySet object we ensure that django will not try to execute any query to db.

Related issues

Closes #2114

Copy link

cla-checker-service bot commented Nov 25, 2024

💚 CLA has been signed

@github-actions github-actions bot added agent-python community Issues opened by the community triage Issues awaiting triage labels Nov 25, 2024
@Pokapiec
Copy link
Author

@xrmx this is the PR i created to resolve this issue #2114 we discussed earlier. I wanted to add this transformation logic to django contrib code but i couldn't make it work so i had to move it to transform func. Let me know if there is a better way.

@gtback
Copy link
Member

gtback commented Dec 11, 2024

cla/check

Copy link
Member

@xrmx xrmx left a comment

Choose a reason for hiding this comment

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

I think we shouldn't poke much with Django internals, also we should not assume django is installed

Comment on lines 148 to 150
elif isinstance(value, QuerySet):
value._result_cache = []
ret = repr(value)
Copy link
Member

@xrmx xrmx Dec 24, 2024

Choose a reason for hiding this comment

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

Suggested change
elif isinstance(value, QuerySet):
value._result_cache = []
ret = repr(value)
elif DjangoQuerySet is not None and isinstance(value, DjangoQuerySet) and getattr(value, "_result_cache", True) is None:
# if we have a Django QuerySet a None result cache it may mean that the underlying query failed
# so represent it as an empty list instead of retrying the query again
ret = "<%s %r>" % (value.__class__.__name__, [])

Instead of erasing the values everytime shouldn't we just do something is value._result_cache is None?

Choose a reason for hiding this comment

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

sure, there is a little less magic to your solution 👌

@@ -36,6 +36,7 @@
import uuid
from decimal import Decimal

from django.db.models import QuerySet
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
from django.db.models import QuerySet
try:
from django.db.models import QuerySet as DjangoQuerySet
except ImportError:
DjangoQuerySet = None

Choose a reason for hiding this comment

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

good point i will change it 👌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
agent-python community Issues opened by the community triage Issues awaiting triage
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Repeating query in django view that failed due to OperationalError (timeout)
4 participants