[DB-SIG] RE: column type casting

M.-A. Lemburg mal@lemburg.com
Fri, 23 Mar 2001 19:24:09 +0100

Federico Di Gregorio wrote:
> Scavenging the mail folder uncovered M.-A. Lemburg's letter:
> [snip]
> > Good idea.
> >
> > There seem to be a few things common to all implementations:
> >
> > * settings are inherited from connection to cursor objects, but
> >   can be overridden on the cursor
> >
> > * argument callback assignment is done in a positional way, meaning
> >   that each argument can be handled individually
> >
> > * type mappings map cursor.description type codes to converters
> the last two items are quite orthogonal, but the basic concept, the use
> of a typecast object or a callback function applies to both. this is why
> i propose the following api that, to me, has some advantages:
> 1/ it is simple (both to use and implement)
> 2/ it is db-independent
> 3/ imho, does it the python-way...
> first of all, the callbacks are callable objects and the old type
> singletons should be implemented as those new objects (everything
> that applies to the old singleton types applies to this new type
> objects.) you can build a new type object by calling the new_type()
> function on the module:
>         TYPE = module.new_type(name, cast_func, type_codes)
> where name is just a string (we can drop it, it is usefull only for
> debugging purpouses); cast_func is a function that takes a data in
> the db _natural_ format (that is a String or Buffer, usually) and
> casts it into the new type and type codes are the codes from
> description.type_code to which the TYPE object should be equal.
> mmm, bad english, example: TYPE == cursor.fetchone().description[1]
> should be true is the type code returned by the db is one of the
> values in type_codes.

This is OK for data input, but how do you specify the case where
you want database output to use a specific type object ?

Note that you have a multiple to one mapping here, so the interface
won't be able to map a specific type code to one well defined
type constructor. Also, the data returned by the database may
be very different from what you pass in on the input side at
Python level, e.g. on input you may have Date(123456) with 123456
being a 1970 based ticks value, but the database generates
1900 based ticks values (OK, this is an extreme example, but you
get the point...) ?
> as i said above, TYPE should be a callable object (it works like a
> callback function) so that doing TYPE(data...) returns the data
> correctly type-casted.
> now that we have types, we can use them in two, orthoganl ways.
> we can register the types with the system (i'll put the function
> in module, because the default types NUMBER, STRING, etc. are
> defined in it, but working on the connection is equally valid)
> by calling:
>         module.register_type(TYPE)
> from now on all the columns that have a type_code included in the
> TYPE's list of type_codes, are concerted by calling TYPE(data) on
> the column data returned by fetchXXX().

Make that connection.register_type(...) and cursor.register_type(...)
with the cursor inheriting the type registrations from the connection.
A module scope registration will only cause problems (thread-wise
and design-wise too).

> what happens if (like in postgres lobs) the type code is not enough
> but u need to convert just a single column? you simply call:
>         cursor.register_type(TYPE, column)
> to associate the TYPE callback to a specific column in a specific
> cursor (i see aproblem here, what happens if the user forget to
> destroy the cursor and reuse it for a different SELECT? maybe
> the data can't be converted and an exception should be raised?)
> that's all. as you see, three functions and an object that is already
> half-implemented in the current driver. this stuff should be fairly
> easy to implement for everyone. and cover almost all cases. what
> do you think about?
> ciao,
> federico
> --
> Federico Di Gregorio
> MIXAD LIVE Chief of Research & Technology              fog@mixadlive.com
> Debian GNU/Linux Developer & Italian Press Contact        fog@debian.org
>   Those who do not study Lisp are doomed to reimplement it. Poorly.
>                                      -- from Karl M. Hegbloom .signature

Marc-Andre Lemburg
Company & Consulting:                           http://www.egenix.com/
Python Pages:                           http://www.lemburg.com/python/