Re: flexi adaption/casting scheme - Mailing list psycopg

From Tobias Oberstein
Subject Re: flexi adaption/casting scheme
Date
Msg-id 505DBC3D.5060308@gmail.com
Whole thread Raw
In response to Re: flexi adaption/casting scheme  (Daniele Varrazzo <daniele.varrazzo@gmail.com>)
Responses Re: flexi adaption/casting scheme
List psycopg
Am 22.09.2012 03:21, schrieb Daniele Varrazzo:
> On Fri, Sep 21, 2012 at 5:42 PM, Ronan Dunklau <rdunklau@gmail.com> wrote:
>
>> I would  be very happy if it is included in a future release.
>
> I've pushed it into my composite-custom branch. I've mixed our
> designs, refactoring CompositeCaster to allow overriding make(), but
> adding a factory parameter to register_composite() to register the
> subclasses the same way the base class is usually created, without the
> from_db/register methods exposed in my previous patch.
>
> An example of usage is in the docs: see
> https://github.com/dvarrazzo/psycopg/commit/fa9393b5870f07d6fb3ac55f5d90ffd8e06fe678#L1R208
>
> Thank you and Tobias for the input. Testing and comments are welcome.
>
> -- Daniele
>

Hi Daniele,

Ok, I'll do testing combining the recent Json + above stuff together.
Thanks for adding nifty features!

1 thing I stumbled over (not related to above stuff):

the _from_db class method on CompositeCaster takes a name argument and
parsed that into "schema" and "typename".

It uses both to retrieve Oids etc, but then only forwards "typename",
and not "schema" to the CompositeCaster constructor.

If a have 2 composite types defined "public.t_foo" and "bar.t_foo", and
register both, one will be overwritten ..

Can we have "schema" in CompositeCaster also?

Today:

     def __init__(self, name, oid, attrs, array_oid=None):
         self.name = name



Proposed:

     def __init__(self, schema, name, oid, attrs, array_oid=None):
         self.schema = schema
         self.name = name

     @classmethod
     def _from_db(self, name, conn_or_curs):

...

         return CompositeCaster (schema, tname, type_oid, type_attrs,
             array_oid=array_oid)



Alternatively, without breaking the API:

     @classmethod
     def _from_db(self, name, conn_or_curs):

...
         c = CompositeCaster (tname, type_oid, type_attrs,
array_oid=array_oid)
         c.schema = schema
         return c


     def __init__(self, name, oid, attrs, array_oid=None):
         self.name = name
         self.schema = ''
         self.oid = oid
         self.array_oid = array_oid

         self.attnames = [ a[0] for a in attrs ]
         self.atttypes = [ a[1] for a in attrs ]

         fullname = self.schema + self.name

         self._create_type(fullname , self.attnames)
         self.typecaster = new_type((oid,), fullname, self.parse)
         if array_oid:
             self.array_typecaster = new_array_type(
                 (array_oid,), "%sARRAY" % fullname, self.typecaster)
         else:
             self.array_typecaster = None


A third alternative:

     @classmethod
     def _from_db(self, name, conn_or_curs):

...

         # forward name instead of tname !
         return CompositeCaster (name, type_oid, type_attrs,
             array_oid=array_oid)



     def __init__(self, name, oid, attrs, array_oid=None):
...
         # namedtuple's cannot have dots in name ..
         self._create_type(name.replace('.', '_'), self.attnames)
...

====

Personally I'd be fine with all .. they all prohibit clashes with
identically named composite types in different schemata and both provide
the ability to get the fully qualified composite type name in the
CompositeCaster instance.

Cheers,
Tobias


psycopg by date:

Previous
From: Daniele Varrazzo
Date:
Subject: Re: flexi adaption/casting scheme
Next
From: Daniele Varrazzo
Date:
Subject: Re: flexi adaption/casting scheme