Opened 10 years ago

Closed 9 years ago

#2829 closed defect (invalid)

I can't clear what looks like a Model-level DB cache

Reported by: plesur@… Owned by: Adrian Holovaty
Component: Database layer (models, ORM) Version: master
Severity: critical Keywords: windows mysql
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

It looks like my models are caching their DB query in a way that I can't clear.

If I call "Model.objects.all()" and then make any changes to the DB with my MySQL client, the results of subsequent Model.objects.all() invocations never changes.

Example, with model PendingAlert:

PendingAlert.objects.all()

[<PendingAlert: PendingAlert object>, <PendingAlert: PendingAlert object>]

(...now, in mysql...)
mysql> delete from pending_alert;
Query OK, 2 rows affected (0.00 sec)

(...now, back in my Django session)

PendingAlert.objects.all()

[<PendingAlert: PendingAlert object>, <PendingAlert: PendingAlert object>]

...I just verified - the first Django session never clears its cache even if I alter the pending_alert table using Django instead of straight in MySQL.

Just to make sure that I have the right mental model here: Isn't Model.objects.all() supposed to create a QuerySet with its own search? Shouldn't these calls be touching the database directly?

Change History (6)

comment:1 Changed 10 years ago by Malcolm Tredinnick

There is no model-level cache or anything like that involved here.

My guess would be that there is an uncommitted transaction floating around somewhere that means the deletes haven't really hit the database. I'll leave this open for now, pending a bit more thinking, but I strongly suspect it's not a Django bug.

comment:2 Changed 10 years ago by plesur@…

Just to add some more data: This definitely isn't an uncommitted transaction. The deletes hit the database, other clients see them, and if I quit my Django process and restart it then it sees the deletes (...but doesn't see any further changes until it's quit and restarted again).

comment:3 Changed 10 years ago by Simon G. <dev@…>

Keywords: PendingAlert added
Resolution: worksforme
Status: newclosed

Resolving as worksforme unless the reporter or anyone else is still having this issue.

comment:4 Changed 9 years ago by ejot <magnus@…>

Resolution: worksforme
Status: closedreopened
Version: SVN

Im also having this issue. Running on svn rev 5637 (did a fresh checkout to test) and MySQL 5.0.41-commynity-nt, all on Windows.

list(Entry.objects.all())
... list of Entry objects
Perform an insert via MySQL commandline client
list(Entry.objects.all())
... same list of objects returned

Had a fellow in #django try the same thing, using sqlite, and he got an updated list returned.

comment:5 in reply to:  4 Changed 9 years ago by anonymous

Component: Admin interfaceDatabase wrapper
Keywords: windows mysql added; PendingAlert removed

Tried using the same django setup as I have on Windows on my debian system and running the same tests... a new list is returned here.

Linux abaddon 2.6.18-4-686 #1 SMP Mon Mar 26 17:17:36 UTC 2007 i686 GNU/Linux
MySQL 5.0.32-Debian-7etch1-log

These is my first attempt ever submitting tickets so I hope Im doing this right :)

Replying to ejot <magnus@derelik.net>:

Im also having this issue. Running on svn rev 5637 (did a fresh checkout to test) and MySQL 5.0.41-commynity-nt, all on Windows.

list(Entry.objects.all())
... list of Entry objects
Perform an insert via MySQL commandline client
list(Entry.objects.all())
... same list of objects returned

Had a fellow in #django try the same thing, using sqlite, and he got an updated list returned.

comment:6 Changed 9 years ago by Simon G. <dev@…>

Resolution: invalid
Status: reopenedclosed

Hmm... I can't replicate this. I'm running OSX, MySQL 5.0.45. Here's what I've done:

In [1]: from t2829.models import *

In [2]: all = two829.objects.all()

In [3]: all
Out[3]: [<1:hello>, <2:fudge>]


# Ok - right here, I open another terminal to a MySQL command prompt, and execute this:
# INSERT INTO t2829_two829 (var1) VALUES ('spork');
# there are now 3 records. 

In [4]: all = two829.objects.all()

In [5]: all
Out[5]: [<1:hello>, <2:fudge>, <3:spork>]

I'm getting the correct answer, and the same happens if I update/delete from within the MySQL client. Are you using MyISAM tables (I am) or InnoDB tables? This may be an outcome of some mysql-level query cache, but I know that if anything changes in a MyISAM table, then the qcache goes, but this might not be the same for InnoDB.

Please - try this out, and see if you can recreate it. Here's the model I've used:

from django.db import models

# Create your models here.
class two829(models.Model):
    var1 = models.CharField(maxlength=20)
    
    def __repr__(self):
        return '<%d:%s>' % (self.id, self.var1)


    class Admin:
        pass
Note: See TracTickets for help on using tickets.
Back to Top