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

Invalidation and case insensitive #231

Open
niekbaeten opened this issue Mar 13, 2017 · 5 comments
Open

Invalidation and case insensitive #231

niekbaeten opened this issue Mar 13, 2017 · 5 comments

Comments

@niekbaeten
Copy link

I have a MySQL database with the collation set to utf8_general_ci (which is case insensitive)

I'm not a 100% sure, but it looks like invalidation isn't triggered correctly in some cases.
The following testcase should succeed if I understand how invalidation works, but it fails:

class CaseSensitiveTests(BaseTestCase):
    def test_case_sensitive(self):
        # Create a category with an uppercase title
        Category.objects.create(title="TEST")

        # Cache the category with lowercase title
        # (which is the exact same object, because MySQL utf8_general_ci is case insensitive!)
        category = Category.objects.cache().get(title="test")
        # Force invalidation (this will only invalidate the uppercase category)
        category.save()

        # This doesn't refetch the category from the database,
        # since this is still cached (invalidation was not triggered for lowercase category)
        with self.assertNumQueries(1): # <--- fails
            Category.objects.cache().get(title="test")
@Suor
Copy link
Owner

Suor commented Mar 13, 2017

Cacheops was never designed to work with case-insensitive text. It could be made to work, solution will require user to specify custom handling of certain fields manually.

I should say that I am not interested in solving this particular case at all. However, this could be possibly implemented in a bigger context of custom field transformations, in importance of which I am not sure either. The idea is to allow user to transform field values used both in invalidation and DNF with arbitrary functions. This can be used to support custom fields and types, truncate dates and longer texts, even invalidate by interval queries.

This requires futher discussion and preferrably more interested people.

@niekbaeten
Copy link
Author

So in above testcase, the one object is actually cached as 2 separate instances (TEST and test)?
I was under the assumption that objects were cached by their PK, but perhaps I should delve a bit more in your code to correctly understand it.

To "fix" the issue I could make sure that query parameters are always send as lowercase right?

@Suor
Copy link
Owner

Suor commented Mar 13, 2017

I think the issue here is that invalidation uses uppercase, which it got from db, but query uses lowercase. Thus .save() does not invalidate that query.

You can read on how cacheops works here - http://hackflow.com/blog/2014/03/09/on-orm-cache-invalidation/

@Suor
Copy link
Owner

Suor commented Mar 13, 2017

P.S. yes, using the same case everywhere will help.

@niekbaeten
Copy link
Author

Thanks, I guess that's what I should look into now.
Perhaps it's an idea to mention this behavior somewhere in the readme, to make this clear for other users.

Feel free to close this issue, as I understand it would take a lot of work to get this working, or leave it open as you said since perhaps more people would be interested in this

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

No branches or pull requests

2 participants