[DB-SIG] spec: named parameters: clarification needed

Anthony Tuininga anthony@computronix.com
Sat, 15 Feb 2003 14:00:08 -0700


On Sat, 2003-02-15 at 09:22, M.-A. Lemburg wrote:
> Anthony Tuininga wrote:
> > The problem is that the spec is not at all clear. Keyword arguments are
> > still arguments -- they are turned into a single dictionary which is the
> > "right" way in Python to pass arguments by name. 
> 
> I'm not sure I can follow you here. The spec talks about a
> single optional parameter which happens to be called parameters
> (plural) and then states -as Harald corrected me- that this
> parameter may either be a sequence or a mapping. That's as clear
> as can be.

Ok, then the spec is deficient, in my opinion. Which is better?

statement = """
    select Column1, Column2, Column3
    from SomeTable
    where Column1 like :p_Arg1
      and Column2 between :p_Arg2 and :p_Arg3
      and Column3 > :p_Arg4"""

Current Requirement (according to your reading)
args = {
    "p_Arg1" : "FRED%",
    "p_Arg2" : 1,
    "p_Arg3" : 10,
    "p_Arg4" : 25
}
cursor.execute(statement, args)

My preference (and more Python like, in my opinion)
cursor.execute(statement,
    p_Arg1 = "FRED%",
    p_Arg2 = 1,
    p_Arg3 = 10,
    p_Arg4 = 25)

If you are claiming that the spec requires a parameter and no keywords,
then I would very strongly suggest that it be amended. Regardless, I
have no intentions whatsoever of complying strictly with the standard as
you read it since it would lead to an annoying loss of functionality. I
think I can safely say that all others that used named parameters would
agree.

> > Creating a dictionary,
> > populating it with arguments and then passing it directly is against
> > normal Python syntax (in my opinion, anyway). I realize that until
> > Python 2.0 you couldn't pass a dictionary that you had prepared in
> > advance (the rare case) as keyword arguments but do we really need to
> > consider compatibility with Python 1.5 still?
> 
> Hmm, I think you are talking about the apply() syntax
> which was added to Python in 2.0... fct(*args, **kws).
> That's syntactic sugar which exploits that arguments
> are treated internally as tuple and keyword arguments
> as dictionary.
> 
> However, that's not how you normally call a function
> which has keywords or multiple parameters.

No way. Take a look at the Python code in the wild. The number of times
that keyword arguments are used is amazing. It happens to be one of
Python's strong points in my opinion. This is particularly common with
use of wxPython which has (often) reams of parameters of which only one
or two are of interest. Requiring a dictionary to be passed which
contains all of the arguments would make this unwieldy in a big hurry.

> > Perhaps what needs to be specified is:
> > 
> > execute(statement, *parameters) --> sequence (for non-named)
> > execute(statement, **parameters) --> mapping (for named)
> > 
> > And this last one for backwards compatibility if necessary
> > 
> > execute(statement, parameters) --> sequence or mapping depending on
> > module.paramstyle
> > 
> > Any thoughts on that?
> 
> IMHO, there's no need to change the spec, only clarify
> it where it is unclear.

Definitely disagree. Let's change the spec to make it clear that keyword
arguments are to be preferred for named parameter passing. Anyone else
who has written drivers with named parameters want to chime in on this
one?

> > On Sat, 2003-02-15 at 03:52, Harald Meland wrote:
> > 
> >>[M.-A. Lemburg]
> >>
> >>
> >>>Anthony Tuininga wrote:
> >>>
> >>>>When I wrote cx_Oracle I assumed 2 but I have lately been told that
> >>>>other drivers have assumed 1 instead, so I am intending to implement
> >>>>both ways. Perhaps this should be clarified in the API document?
> >>>
> >>>That's why I put up the question. Note that the .executeXXX()
> >>>APIs only define one parameter which is defined as sequence
> >>>or sequence of sequences, so both options conflict the spec
> >>>in some way.
> >>
> >>Huh?  From the current spec, and I think this has been in there for
> >>quite some time:
> >>
> >>    .execute(operation[,parameters])
> >>          
> >>        Prepare and execute a database operation (query or command).
> >>        Parameters may be provided as sequence or mapping and will be
> >>                                               ^^^^^^^^^^
> >>        bound to variables in the operation.
> >>
> >>Similar wording is used for .executemany().
> >>
> >>To me, that's pretty clear; am I missing something?
> >>
> >>
> >>>Given that most drivers which use this param style seem
> >>>to implement option 2, I guess we should allow keyword
> >>>parameters to the .executeXXX() methods as well (provided
> >>>that .paramstyle is set to 'named').
> >>
> >>Umm, if the spec is changes to allow leniency here, it will *further*
> >>complicate the matter of "my application needs to change database
> >>driver, and hence I need to transform lots of .execute*() calls for
> >>purely non-SQL differences".
> >>
> >>Is that really wise?
> >>
> >>If some drivers want to implement args as keyword params, they're
> >>obviously free to do so, but I'd prefer the spec to stay as it is
> >>(modulo better wording if necessary, of course).
-- 
Anthony Tuininga <anthony@computronix.com>