Accueil / Blog / Métier / Archives / Cheap debugging of PostgreSQL triggers in Django

Cheap debugging of PostgreSQL triggers in Django

Par Mathieu Leplatre 22/10/2012

Lately, we were hacking on PostgreSQL (PostGIS) triggers, and we quickly felt like debugging our code... Here is a cheap and quick way of printing out triggers variables and context through Django.

PostgreSQL server configuration

In postgresql.conf, adjust the minimum level of notice sent to the client :

client_min_messages = log

Note that this does not affect logging verbosity on server.

Catch messages in Django

For a specific model :

from django.db import connection

def save(self, *args, **kwargs):
    before = len(connection.connection.notices)
        super(Model, self).save(*args, **kwargs)
        for notice in connection.connection.notices[before:]:
            print notice

Or globally, using post_save signals (can be verbose):

from django.db import connection
from django.db.models.signals import post_save

def show_notices(sender, instance, created, **kwargs):
    for notice in connection.connection.notices:
        print notice

Let your trigger be talkative

You can basically print out values, arrays, functions results, records...

RAISE LOG '% has geom %',, ST_AsEWKT(NEW.geom);

Will output something like LOG:  3 has geom SRID=4326;POINT(0 0).

FOR record IN SELECT * FROM table
    RAISE LOG 'Found %', record;

Will output something like LOG:  Found (a,b,c).

intersections_on_new := ARRAY[]::float[];
FOR pk IN SELECT ST_Line_Locate_Point(NEW.geom, (ST_Dump(ST_Intersection(other.geom, NEW.geom))).geom)
    intersections_on_new := array_append(intersections_on_new, pk);
RAISE LOG 'Intersects at %', intersections_on_new;

Will output something like LOG:  Intersects at {0.5,0.3}.

One more thing...

If you load your triggers source file through Django (like a post_migrate signal or so), and thus with psycopg2, you might face that nasty internal quirck :

postgresql_psycopg2/", line 52, in execute
    return self.cursor.execute(query, args)
IndexError: tuple index out of range

This is due to % characters, that you have to escape, replacing them with %%.

Mots-clés associés :
Voir aussi
Optimiser ses tests unitaires Django avec setUpTestDataOptimiser ses tests unitaires Django avec setUpTestData 22/06/2015

Découvrez comment gagner en efficacité sur les tests unitaires avec Django 1.8 et sa nouvelle ...

Alerte à la pollution en Méditerranée ! 22/10/2008

Makina Corpus réalise pour le Centre Régional Méditerranéen pour l’Intervention d’Urgence ...

Retrouvez Makina Corpus au DjangoCong (14 et 15 avril 2012) 10/02/2012

Lors de la grand messe des Djangonautes français, Mathieu Leplatre vous expliquera comment publier ...

Makina Corpus sponsor du Capitole du Libre 2012 19/11/2012

Cette année encore, et ce depuis au moins 2009, Makina Corpus sponsorise l'événement du Logiciel ...

Drupal and Jenkins: continuous integration howto 07/12/2011