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
Queryset with annotated Now() is cached #193
Comments
This comment has been minimized.
This comment has been minimized.
@Andrew-Chen-Wang: this is a constructed case of course which I came up with: so there is no need for a temporary cure. One feasible approach would be to do an additional check at: django-cachalot/cachalot/utils.py Line 176 in 9d52865
Wouldn’t it be most obvious to simply deactivate caching - on the lines of how the django-cachalot/cachalot/utils.py Line 117 in 9d52865
Another questionI also noted that annotated condititional expression do not seem to be handled? Is this perception correct? |
Ah I just noticed the django-cachalot/cachalot/tests/read.py Lines 1034 to 1046 in 9d52865
Did you happen to have this behavior on Django 3.1 and/or on previous cachalot versions? Django 3.2 brought a weird change that had deeply hidden nuances, and the changes I made or Django made may have affected the ORM module.
That's OK for a temporary solution, but it doesn't resolve the worry that these annotations aren't being caught in the utils.py on L117.
They are handled I think; though, I suppose we don't have a test case for Case or Where specifically. |
We have been using cachalot for only two weeks now and as we are always on the latest LTS Django version, we have only tested it with Django 3.2.
Is it ok for you if I open a new PR with additional tests that demonstrate use cases which are not handled yet? In a further step we could then try to fix these cases in the same PR. What do you think? |
Approved the CI. Thanks for the quick write-up! |
@dbartenstein thanks for the quick test and great bug reports. Both are resolved in #195 and #196 |
@Andrew-Chen-Wang: wuhu - you’re quick! 👍 I’ll have a look at our code base and check it for additional sophisticated queries which might not yet be covered by cachalot. For many uses cases not caching a query is better than falsely not invalidating one. What do you generally think of introducing a setting |
Can you specify where this setting would be used? Cachalot is pretty algorithmic, so we can't really tell if we're missing something or not or making a false positive besides tests. Do you mean when we add new behaviors? In which case, I haven't added any significantly new features, besides some new settings; everything's in maintenance mode since it's been working fine for me. |
It was more like an idea. When we added cachalot we realized that there were cases where unwanted caching happened - due to the fact that not all cases were handled (e.g. annotated Edit: to be on the safe side, one could additionally check the resulting SQL |
I thought about it before, and it's not that bad in terms of code (it was pretty bad in terms of performance tho), but it isn't necessary since the bug reports found here or, in general, a conservative approach, misses the core dilemma: where do we even look for these expressions? Plainly, it's the ever-changing internals of the ORM and the lack of variety in the test suite that cause issues. For example, Django uses the RHS/LHS concept, and for all of cachalot history, only in Django 3.2 have I needed to add support for checking the LHS. Or the introduction of inner_query: django-cachalot/cachalot/utils.py Line 201 in b15027a
Taking a conservative approach vs. a liberal approach both end up at this "where do I look" dilemma. If we were to check all expressions (the conservative approach), how would we know that we checked every single QuerySet class method that might contain a cachable expression? Same vice versa for the liberal approach: how do we know we caught all the uncachable expressions? So it boils down to:
|
👍
👍 Yesterday I experimented a bit with an additional SQL check - at the end of
One of the tests which surprised me at first:
LearningThe ordering by Changing content types’ labels would result in different queryset order.
|
The Content Type app is used by several packages and Django internally quite a lot, so it's fine (all tables are invalidated on migration). In general, if someone specifies There are many things Django does behind the scenes that you don't specify explicitly in an ORM query or inside your view.
I can really only answer this in two parts:
|
What happened?
An annotated query including
Now()
is cached.What should've happened instead?
An annotated query containing
Now()
must not be cached.Steps to reproduce
Debian Linux
Django version 3.2 LTS
Postgresql 10
The text was updated successfully, but these errors were encountered: