[DB-SIG] In praise of pyformat

Mike Meyer mwm-keyword-dbsig.588a7d at mired.org
Sat Aug 11 18:12:57 CEST 2007


On Sat, 11 Aug 2007 09:13:57 -0400 Carsten Haese <carsten at uniqsys.com> wrote:

> On Sat, 2007-08-11 at 04:25 -0400, Mike Meyer wrote:
> > On Fri, 10 Aug 2007 20:24:17 -0400 Carsten Haese <carsten at uniqsys.com> wrote:
> > > As I said, there is a defined way: Don't treat things that look like
> > > parameter markers as parameter markers if they appear inside
> > > apostrophes. This may require a simple parser in the API module, but I
> > > prefer placing a burden on a dozen API module authors over placing a
> > > burden on thousands of application developers.
> > 
> > Well, that's a way. The problem is, it's not defined in the PEP. Other
> > modules don't do that (since pysqlite is bundled these days, it's easy
> > to verify that indeed, it doesn't behave this way).
> 
> Sure, let's verify:
> 
> >>> import sqlite3
> >>> conn = sqlite3.connect(":memory:")
> >>> cur = conn.cursor()
> >>> cur.execute("create table t1(c1 varchar(20))")
> <sqlite3.Cursor object at 0xb7ecec20>
> >>> cur.execute("insert into t1(c1) values('?')")
> <sqlite3.Cursor object at 0xb7ecec20>
> >>> cur.execute("select * from t1").fetchall()
> [(u'?',)]
> >>> cur.execute("insert into t1(c1) values(?)")
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> sqlite3.ProgrammingError: Incorrect number of bindings supplied. The
> current statement uses 1, and there are 0 supplied.
> 
> Maybe I'm misunderstanding what you mean by "behave this way", but it
> certainly looks like it's doing what I described as "Don't treat things
> that look like parameter markers as parameter markers if they appear
> inside apostrophes."

The definition was vague, and I assumed "treat all other things that
look like parameter markers as parameter markers." Possibly that's
wrong, and there are other cases. But that's what breaks:

>>> c.execute('insert into foo (id) values ("?")', [23]) 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 0, and there are 1 supplied.

Likewise, I understand that Informix has a couple of cases where it
uses colons outside of literals. So if I need one of those, we're back
to the question of "How do I make the apostrophes go away?". A rule
that only needs to be applied sometimes, and when those times are
varies from module to module isn't much better than no rule at all.

Actually, I think that highlights the while problem with trying to
take this burden off the user: you're making when things that look
like parameter markers are really parameter markers implicit rather
than explicit. If there's a simple-to-apply rule (that's in the spec
so we can depend on every module to use it and the users know what it
is), this isn't so bad. But there also needs to be a way to deal with
cases where you need a parameter marker that's not covered by the
rule.

format/pyformats rule - "If you need a bare %, put in two" is not only
simple for the module implementors, it's simple for the users to deal
with.

      <mike
-- 
Mike Meyer <mwm at mired.org>		http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.


More information about the DB-SIG mailing list