Query trotz Cache

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Farbflut
User
Beiträge: 10
Registriert: Mittwoch 9. April 2008, 16:50

Hallo,
ich bin gerade dabei ein wenig mit memcached und db_cache zu spielen.
Um zu überprüfen welche Abfragen kommen, habe ich mich erstmal für db_cache entschieden.

Ich dachte es wäre ganz einfach, wenn ich ein Objekt benötige, schaue ich ob es im Cache ist und wenn nicht, starte ich eine Abfrage und schieb es in den Cache.

Nun, das ganze funktioniert auch soweit. Doch wenn ich das originale SQL Object in den Cache lege, starte er dennoch immer eine Abfrage auch wenn ich es aus dem Cache lade.

Die View:

Code: Alles auswählen

def highscore(request, page=1):
    cache_check = cache.get('highscore')
    if cache_check:
        highscore = cache_check
    else:
        highscore = list.objects.filter()
        cache.set('highscore',highscore,24*60*60)
	    
    cache_check = cache.get('city_list')
    if cache_check:
        city_list = cache_check
    else:
        city_list = stadtteile.objects.all().order_by("name")
        cache.set('city_list',city_list,6*60*60)
	
    return game_render(request, 'highscore/highscore.html',{'highscore':highscore, 'current_page':int(page),'city_list':city_list})
Zu diesem View die SQL Queries:

Code: Alles auswählen

SELECT cache_key, value, expires FROM dbcache WHERE cache_key = highscore  	0.001
SELECT `highscore_list`.`id`,`highscore_list`.`uid`,`highscore_list`.`name`,`highscore_list`.`punkte`,`highscore_list`.`premium`,`highscore_list`.`bande_name`,`highscore_list`.`city_id` FROM `highscore_list`
Man sieht, hier ist etwas doppelgemoppelt und sicherlich nicht der Sinn des cachens :D

Da ich mir schon dachte, dass es am Objekt liegt habe ich mir ein Workaround gebaut:

Code: Alles auswählen

def highscore(request, page=1):
    cache_check = cache.get('highscore')
    if cache_check:
        caching = cache_check
    else:
        highscore = list.objects.filter()
        
        caching = []
        for data in highscore:
            array = {'id':data.id,'uid':data.uid,'name':data.name,'premium':data.premium,'punkte':data.punkte,'bande_name':data.bande_name,'city_id':data.city_id}
            caching.append(array)
            
        cache.set('highscore',caching,24*60*60)
	    
    cache_check = cache.get('city_list_highscore')
    if cache_check:
        city_list_cache = cache_check
    else:
        query = stadtteile.objects.all().order_by("name")
        city_list_cache = []
        for data in query:
            array = {'id':data.id,'name':data.name}
            city_list_cache.append(array)

        cache.set('city_list_highscore',city_list_cache,24*60*60)
	
    return game_render(request, 'highscore/highscore.html',{'highscore':caching, 'current_page':int(page),'city_list':city_list_cache})
Jedoch finde ich das alles andere als nützlich.
Gibt es vielleicht eine einfachere Methode?

Danke
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Der Typ `list` hat kein Attribut `objects`. Irgendwie ist dein Beispielcode nicht vollständig oder nicht korrekt. Ich rate anhand des `objects` mal, du benutzt Django. Leider verschweigst du solche Details. Bei Django wird ein QuerySet erst dann wirklich ausgeführt, wenn das Ergebnis benötigt wird. Was du cachen willst, ist aber nicht das QuerySet, sondern dessen Ergebnis. Also z.B.

Code: Alles auswählen

city_list = cache.get('city_list')
if not city_list:
  city_list = list(Stadtteile.objects.order_by('name'))
  cache.set('city_list', city_list, 6 * HOURS)
Stefan
Farbflut
User
Beiträge: 10
Registriert: Mittwoch 9. April 2008, 16:50

Super, danke. Ja ich verwende django.
Dass man nicht selbst auf diese absolut einleuchtende Lösung kommt -_-
Man denkt immer viel zu kompliziert...
Antworten