[DB-SIG] API 3.0 limiting paramstyle to ['named', 'qmark'] is okay. ('format' is not desirable)

Daniele Varrazzo daniele.varrazzo at gmail.com
Sat May 18 03:29:22 CEST 2013

On Fri, May 17, 2013 at 5:57 PM, M.-A. Lemburg <mal at egenix.com> wrote:
>> Reading back the upstream thread I also see proposal to leave support
>> for all the current placeholders but mandate drivers to implement
>> qmark and named too. I think this is only going to complicate the
>> implementation of the drivers and of the programs using it.
> Why is that ?

I'll try to explain that again. Let's say I work in a postgres-only
shop: currently there is no interoperability problems, and people
writes python-postgres programs and py-pg libraries. Let's say
psycopg3 (implementing dbapi3) implements a method to switch
paramstyle, whatever it is.

Alice is writing a script program, reading the database, doing some
business-related math and generating a report. Of course the business
model is already implemented in the well tested and uniformly used
"shoplib" library, written by Bob: this library takes a psycopg2
connection and runs whatever complicated query they need to implement
such model.

In dbapi2 this is a piece of cake. In dbapi3 Alice is free to have her
opinions: she is hip and dbapi3 is all the rage, so she will create a
psycopg3 pyformat connection and pass that to the shoplib: of course
the program will crash and burn immediately. Alice may point out that
Bob is not providing complete support to a valid psycopg connection.
There are two possible outcomes: 1. most likely Alice will be laughed
at and the shop will assume a policy of not using different paramstyle
than pyformat, hence making impossible to use libraries or frameworks
(sqlalchemy, django) that would of course benefit of the uniformly
used named format; 2. Alice is good enough into talking everybody that
dbapi3 is the future: now Bob in order to offer the shoplib service to
psycopg connection in either mode will have to jump through hoops: he
will either store the paramstyle of the connection received in a
temporary variable, switch it to pyformat and finally restore it (with
all the concurrency problems this would involve, as the connection may
be shared across threads); or he will have to dynamically generate
queries that would have otherwise been expressed as string constants.

This is the reason why I firmly believe that giving excessive freedom
to the users when designing a standard only means troubles not only
for who implements the service (the dbapi driver in our case) that has
to implement several equivalent options, but also for the users of
such driver, because writing a function library accepting connections
that may demand different parameter style is much more complicated
than one where you would just have done with a string, and offers new
and unexpected modes of failure. Doing that only to second stylistic
matters would be just irresponsible.

If we are designing a standard we have to make decisions: every
decision we don't make and leave to somebody else only increases the
complexity, doesn't definitely add democracy and peace in the world.
And open choices don't increment complexity in additive way: they do
it rather in multiplicative way.

My thoughts about the specific issue in this thread (not my wishlist
for dbapi3, with which I'll be glad to bore you to death in another
thread) is that

1. demanding a single paramstyle for the driver will only make
millions of people angry

2. making the paramstyle switchable will result in programs more
complicated, libraries *way* more complicated and database drivers
*way, way* more complicated, inevitably causing bugs on either side,
making millions of people angry

3. leaving the things as they are w.r.t. the paramstyle (and fix the
several shortcomings that dbapi 1 and 2 have shown in the about 10
years they have been around) would make a dbapi3 more gradually
acceptable and not a watershed event. And would leave a couple of
people angry, which have chosen as mission in their lives to write
compatibility layers on top of dbapi modules :) Sorry Michael, you
were a good developer but I'd rather sacrifice you than million of
people :)

Out of joke, Michael, I know that wrestling the idiosyncrasies of each
and every dbapi module must feel like herding cats, but I don't
believe the different paramstyles are the biggest of the issues you
have to solve. I bet bigger problems are in the different syntax
offered by the database servers, different data type supported and
different ways to represent them, different ways to perform
introspectiAnd after on and who knows what else (well, you do :). With
postgres that wants "select ... from a join b on a.id = b.a_id" and
informix that wants "select ... from a, outer b where a.id = b.a_id" I
just don't think a common placeholder is going to be a decisive help
for anybody who wants to deal with database abstraction layers.

Oh, yes, and there was 4. "have the driver automatically detect the
paramstyle". Please, don't joke: this idea is so brittle it's not even
funny to demand it as part of a standard.

> I think it would greatly simplify the use of the DB-API, since
> applications could then be written to use a single paramstyle,
> even when using multiple database modules.

Come on, you are a database expert: do you really believe that because
two commands can be written with the same paramstyle it would be
possible to send the same query to different databases? With so
different sql syntaxes, so different data models, so different runtime
models? I don't think interoperability across database is a problem
that can be solved at dbapi level: the aim of the dbapi (and the
benefit it has provided in its not short life) is to provide
uniformity in the python code to access a database; I don't think it
being a database abstraction layer has ever been its scope.

-- Daniele

More information about the DB-SIG mailing list