1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# -*- coding: utf-8 -*-
import datetime
from django.core.management.base import NoArgsCommand
from django.conf import settings
from django import db
import time

SESSION_DELETE_BULK_SIZE = getattr(settings, "SESSION_DELETE_BULK_SIZE",
                                                                        10000)

class Command(NoArgsCommand):
    """With InnoDB, the naive DELETE query will completly lock the
    session table even for reads and the session table will become unusable.

    This script is a workaround that will first select a certain
    amount of sessions and then delete them by ID. This will not lock
    the entire table but only the selected sessions."""
    
    help = "Cleanup the sessions table without locking the whole table."

    def handle_noargs(self, **options):
        from django.contrib.sessions.models import Session
        now = datetime.datetime.utcnow()
        print "Searching for old sessions..."
        while True:
            print "SQL query for %d sessions" % SESSION_DELETE_BULK_SIZE
            sessions = Session.objects.filter(
                        expire_date__lt=now
                    ).values('session_key')[0:SESSION_DELETE_BULK_SIZE]
            if not len(sessions):
                break
            print " ¦- found %d sessions." % len(sessions)
            key_list = [s['session_key'] for s in sessions]
            Session.objects.filter(session_key__in=key_list).delete()
            print " `- all deleted."
            print ""
            # without this sleep I encountered some strange lock issues on
            # other tables of the database.
            time.sleep(15)
        print "Finished"