Custom PG Range: where to place register_range() call?

76 views
Skip to first unread message

Javi

unread,
Nov 22, 2016, 12:17:19 PM11/22/16
to Django users
I was following the documentation at https://docs.djangoproject.com/en/1.10/ref/contrib/postgres/fields/#defining-your-own-range-types in order to create a custom range.

It says that I have to use the function register_range() from psycopg2. I suppose that the code should be something like this:
from psycopg2.extras import register_range
TimeRangeCaster = register_range('timerange', 'TimeRange', conn_or_curs=???, globally=???)
TimeRange = TimeRangeCaster.range


Suppose that previously I had executed this on postgresql
CREATE FUNCTION time_subtype_diff(x time, y time) RETURNS float8 AS
'SELECT EXTRACT(EPOCH FROM (x - y))' LANGUAGE sql STRICT IMMUTABLE;

CREATE TYPE timerange AS RANGE
(
    subtype
= time,
    subtype_diff
= time_subtype_diff
);


1) Is register_range() supposed to go in app.py, AppConfig, models.py or where?
2) In order to integrate this in a django app. Should I use the argument globally=True for register_range()? Should I pass a connection or cursor for the argument conn_or_curs?

Javi

unread,
Nov 22, 2016, 5:28:00 PM11/22/16
to Django users
I found a way to do it. For those interested take a look at https://github.com/djangonauts/django-hstore/blob/master/django_hstore/apps.py

That example solves the problem for register_hstore() but it can be extrapolated for register_range() as well.

The method is the following, in the file apps.py of your app create a ready() method for the AppConfig child class. Inside it create a hook using the signal functionality of django for database connection creation, that is, use connection_created.connect(connection_handler). The argument connection_handler is the function that should call register_range() for the connection provided by connection_created. Registration is done for connections and it can be globally, in which case the hook is a one off event or it can be not globally, in which case the hook is called for every connection established. Reading on the issues of that app, it seems that doing it globally is great for simple apps, but it doesn't deal well with complex setups using multiple databases.
Reply all
Reply to author
Forward
0 new messages