Dear Carsten, et al.,
Carsten Haese wrote:
On Thu, 2007-05-03 at 15:04 -0400, Art Protin wrote:
First, I believe that nothing returned from a call to
cursor.fetchXXX()
should be of a type bound to the API/interface. I recognize that this
is
a difficult constraint but the values need to usable by some
application
written in Python and may even need to written to a different DBMS.
I see the role of the interface to make the data available in pure
Python
form. (So this argues against the proposal by Carsten Haese, I think.)
I agree, and I have changed my proposal significantly to remove the
"welding" of output data to a specific interface. However, I don't agree
with the absoluteness of the assertion that "nothing returned from a
call to cursor.fetchXXX() should be of a type bound to the
API/interface." For example, Smart Blobs from an Informix database
wouldn't have any meaning in any other database, so I think it's
acceptable that they are returned as objects from the informixdb module.
However, as long as the statement is understood to be about standard SQL
types, I have no problem with it.
As I have said (or should have said) "I overstate my case(s)". However,
I still
think this is a good first order approximation.
Database specific information can almost never be handled in a generic way
and what can be made generic should not be tied to types in the API.
(This opens the question to how to design DBMS specific features in a way
that maximizes transference of training for our users. Or is that what we
were already working on?)
[lengthy discussion of main types and sub types...]
In the context of my type mapping proposal, for output mapping it is the
API's responsibility to convey enough information in the type key so
that the mapping can determine which adapter to call.
How does this contrast with what I said?
For your database,
this might be a tuple of main type and subtype. The application is free
to use a mapping that dispatches to an adapter function solely based on
the main type and have the adapter branch on the subtype, or use a
mapping that uses both pieces of information for making the choice of
adapter function.
Sorry. Does "have the adapter branch on the subtype" mean that you accept
the need for the type information to be passed as a second argument to the
adapter function? [Looks like you say that below.]
[export and import functions...]
Associating an import function *and* an export function with the
database type information is problematic. I don't have a problem with
what you call import functions. They seem to serve the same purpose as
the adapter functions in the outputmap in revision 2 of my proposal.
(Your naming of mapping directions is from the application's point of
view, whereas mine is from the database's point of view following the
semantics established by the naming for the setinputsizes and
setoutputsizes methods.)
Sorry. Both the .setinputsizes() and the .setoutputsizes() methods are
implemented
identically on my system -- they do nothing. Viewing the API from the
database
is wrong in only the most subtle of ways. The purpose of the API is to
unite us all
in specifying common functionality for Python users. Thus, when we work
on the
spec. we really need to view our personal DBMS as the outside. This
will help to
produce an API that is Pythonic and that our user base (our Python user
base) will
be comfortable with and thereby will be productive with.
On the other hand however, coupling an import function with an export
function that's looked up based on the database-side type information is
not a good idea, for various reasons. In general, when binding
parameters to a query, the parameter need not be destined for a database
column. Parameters can appear in the WHERE clause of a select statement,
and it's not guaranteed that the underlying database has any way of
finding out what type of datum should be bound to such a parameter.
Good point!
Also, even if this information were available, the process for binding
an application object to, say, a character column would depend very much
on what kind of application object it is. A string can be passed on
verbatim, a unicode object needs to be encoded, and a Geometry object
might need to be translated into OpenGIS Well-Known-Text format. If the
export function were looked up based on database type, those three cases
would all have to be handled by the same export function, which seems
utterly ridiculous to me.
I had a problem seeing the forest for the trees. Or is that the design
for the code.
Anyhow, the export functions can examine a Python object to determine
its type,
so I figured that the mapping function would need to encode the missing
information.
Alas, you show that can not be. And I find that the task of
transforming data from
the form the application likes to the form the DBMS likes must be split
in to two
portions, each hard coded. The application must get the data into "base
Python types"
and the driver must accept all "base Python types" and do such
conversions as is
needed for the DBMS. The mapping of Python types to DBMS types and the
writing
of all needed adapter functions falls on the API driver implementor alone.
(I find it painful to realize that writing the best, cleanest interface
means not
writing any more code, at least not for this feature.)
It makes much more sense to map input parameters based on the type of
Python object that is provided as the parameter value, and that's the
inputmap that I'm proposing. That way you get two separate mappings for
the symmetric purposes of:
* Given a value and type from the database, map it to an application
object, and
* Given a value and type from the application, map it to a database
object.
I don't mind supplying information about the database-side type to the
adapter functions as optional parameters if this information is
available, but determining the export function based on this is in my
opinion not feasible for the reasons I stated above.
Best regards,
Thank you all,
Art Protin
_______________________________________________
DB-SIG maillist - DB-SIG@python.org
http://mail.python.org/mailman/listinfo/db-sig