[DB-SIG] Controlling return types for DB APIs

Robert Brewer fumanchu at amor.org
Sat Apr 21 02:28:04 CEST 2007

Anthony Tuininga wrote:
> cursor.setdefaulttype(databaseType, type)
> connection.setdefaulttype(databaseType, type)
> What this method would do is specify that whenever
> an item that is represented on the database by the
> given database type is to be retrieved, the specified
> [Python] type should be used instead of the default.
> This would allow for a global or local specification
> that numbers are to be returned as strings or
> decimal.Decimal objects or that strings are to be
> returned as unicode objects, for example.
> cursor.settype(position, type)
> This would allow specification of the type to use
> for a particular column being fetched.

As soon as you provide cursor.settype(dbtype, pytype),
you should expect someone to ask for
"pytype = cursor.gettype(dbtype)", and once you've written
that, you'll realize they're both spelled better as
"cursor.types[dbtype] = pytype" (for set) and
"pytype = cursor.types[dbtype]" (for get). Same thing
goes for adapters: once you allow people to set them,
you should expect people will want to inspect them.
So a cursor.adapters object (copied from a similar
connection.adapters object) should be used. Namespaces
are one honking great idea. The container classes don't
*have* to use slicing (you could go all Java-ish and
use get() and set()), but slicing is the most natural
choice in this case.

You also should be very explicit about the direction
of each operation when building type- or language-
translation layers. That is, include the direction
in the names of every method and object, because at
some point, people will want to do the reverse.
A Python method named "coerce" is not as good as a
method named "coerce_in" or "coerce_from_database";
the namespaced spelling, "adapter_in.coerce" is even

> registeradapter(type, databaseType, fromPythonMethod,
>     toPythonMethod)
> This would specify that whenver an object of the given
> [Python] type is bound to a cursor, that the
> fromPythonMethod method would be invoked with the
> value and would expect a return value that can be
> directly bound to the databaseType. The toPythonMethod
> method would be invoked when columns are retrieved and
> would accept the databaseType value and expect back a
> value of the given type.

That sounds good if by "databaseType" you mean
"class VARCHAR"; that is, a Python type which models
a database type. Because there's no such thing as a
"database value" you can pass to a toPythonMethod;
it *must* have already been converted into some Python
object of a Python type (unless you're writing your
adapters in C). The best you can do is have a Python
type (designed/selected for minimum information loss)
to which the incoming value gets coerced before
passing it to your toPythonMethod for further
adaptation or casting.

Robert Brewer
System Architect
Amor Ministries
fumanchu at amor.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.python.org/pipermail/db-sig/attachments/20070420/10695523/attachment.htm 

More information about the DB-SIG mailing list