Re: JSON type caster

From: Tobias Oberstein <tobias(dot)oberstein(at)gmail(dot)com>
To: Daniele Varrazzo <daniele(dot)varrazzo(at)gmail(dot)com>
Cc: psycopg(at)postgresql(dot)org
Subject: Re: JSON type caster
Date: 2012-09-19 13:42:33
Message-ID: 5059CBC9.4030201@gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: psycopg

> Uhm... but what about a new function? To be called
>
> psycopg2.extras.register_default_json(globally=True, loads=loads)
>
> or
> conn = psycopg2.connect(...)
> psycopg2.extras.register_default_json(conn, loads=loads)
>

+1 for that:

it provides a simple to use interface for the use case "PG >=9.2 and
global custom json"

>> Another thing that's probably inconvenient: psycopg2.extras.Json
>> forwards kwargs for customization, but there is no trivial way
>> of using a different "json" implementation altogether
>
> What I didn't like reviewing the two sides is the asymmetry: adapter
> taking **kwargs and typecaster taking loads function. I'm thinking
> about passing a dumps function instead of the **kwargs. It could be:
>
> class Json(object):
> def __init__(self, adapted, dumps=None):
> self.adapted = adapted
> self._dumps = dumps is None and json.dumps or dumps
>
> def dumps(self):
> return self._dumps(self.adapted)
>
> def getquoted(self):
> s = self.dumps()
> return QuotedString(s).getquoted()
>
> This way customization can be performed either functional-style via a closure:
>
> def CustomJson(adapted):
> return Json(adapted,
> dumps=lambda x: simplejson.dumps(x, parse_float=Decimal))
>
> or oo-style via subclassing:
>
> class CustomJson(Json):
> def dumps(self)
> return simplejson.dumps(self.adapted, parse_float=Decimal)
>

+1 for that also ..adding dump argument and dropping kwargs forwarding,
because customizing via kwargs on a per Json-instance basis is probably
the less likely case compared to "I want to use one custom loads/dumps
everywhere".

Probably the default dumps used within Json (when no specific dumps arg
was given) could even come via register_default_json i.e. when doing

psycopg2.extras.register_default_json(
globally = True,
loads = simplejson.loads,
dumps = simplejson.dumps)

which would make the symmetry accessible from 1 function.

The provided dumps would need to be stored at module level somewhere to
be accessible within Json

self._dumps = dumps is None and psycopg2.extras._dumps or dumps

Again, the argument would be that a likely use case is PG>=9.2 and
wanting to install global json loads/dumps used everywhere.

The simpler the API for that, the better. IMHO.

Wait, a problem with above: in the "per-connection variant"

psycopg2.extras.register_default_json(
conn,
loads = simplejson.loads,
dumps = simplejson.dumps)

where to store dumps so that Json instances can access it?

Mmh. There is still some asymmetry: loads is configured
globally or per connection, dumps is configured "per argument instance"
(Json instance) ..

> Thank you for the review. Comments?
>
> -- Daniele
>

In response to

Responses

Browse psycopg by date

  From Date Subject
Next Message Daniele Varrazzo 2012-09-19 15:43:54 Re: JSON type caster
Previous Message Daniele Varrazzo 2012-09-19 13:12:56 Re: JSON type caster