|
From: Ian B. <ia...@co...> - 2003-05-28 17:38:46
|
On Tue, 2003-05-27 at 18:21, Magnus Lyck=E5 wrote:
> I doubt it :). The sqlite driver and the related PostgreSQL driver both
> look for an attribute called '_quote', which I suppose they use for the=
ir
> internal wrappers for SQL types that don't quite match SQL. (MONEY etc)
> That's where I got the idea, and someone on the db-sig list suggested
> that adding type information was needed as well. Perhaps I can at least
> convince Gerard H=E4ring to rename _quote to _dbapi_string in his drive=
rs?
I was thinking of changing the magic method I use to __sqlrepr__, which
seems like a good name to me. Just having a single convention would be
a start.
Right now I think quoting would probably best be done like:
* Integers, floats, strings are all automatically quoted. Maybe
mxDateTime and datetime objects too. No hooks for these -- the
underlying C driver may want to handle these data structures on its own
anyway.
* Anything with a __sqlrepr__ method has that called, with no
arguments. The result is expected to be fully quoted.
* If both those fail, then there's a function which has one last chance
to return a SQL representation on the object. This would be for quoting
types that you couldn't add a __sqlrepr__ method to -- for instance, if
mxDateTime objects weren't automatically handled, you might handle them
here. Usage something like:
import dbdriver
old_quote =3D dbdriver.quote
def quote(val):
if type(val) is DateTimeType:
return val.strftime("'%c'")
else:
return old_quote(val)
Maybe there's a better way to phrase this hook, but this might be
sufficient. The last quoting technique would probably be the only way
to add your own quoting that was database-specific (as would be
necessary with Access and mxDateTime objects). So maybe __sqlrepr__
should actually just be part of the standard quote function.
> Hopefully *someone* will like the idea. Maybe with a few more champions=
... :)
>=20
> A PEP might be a good idea. Another idea I had was to write some short
> generic DB-API tutorial that clarifies all the required features of
> the current DB-API spec. Don't have time for either right now though.
> Both bookkeeping and paying customers need priority handling... :)
Yeah, I hear that. I have to cut myself off from this stuff every so
often.
> >I would still disagree, at least for SQLObject. Or rather, I would sa=
y
> >that separate parameters is a decision that in most places is delayed
> >quite a ways (until your connection is just about to send the SQL), so
> >it's not a big deal either way.
>=20
> My though was to allow .select("name=3D?", ("Guido's",)) as an alternat=
ive
> to .select("name=3D'Guido''s'")
Yes, if you didn't use literals (at least string literals) in the code
it should be okay. =20
> >Well, for instance, MySQL allows strings like 'that\'s it', which woul=
d
> >break this. But it also allows 'that''s it', so maybe people will jus=
t
> >have to use the one.
>=20
> sql.replace(r"\'", "''") before the re would handle that otherwise.
> As a coder I think it's best to follow SQL given a choice, so I'd
> suggest using '' rather than \'.
The replace doesn't work for '\\', though. =20
> In the worst case I can just write a small C (or Pyrex?) routine to
> do this without re. After all, there isn't a lot of SQLism in this,
> is there. A ? should be replaced with ...something... unless it's
> in a quote. A quote started with " should end with " unless the
> preceeding character was \, and a quote started with ' should end with
> ' unless the preceeding character was \. 'That''s' can be seen as two
> quoted areas from a ? replacement perspective.
>=20
> Is there a flaw in that strategy?
Parsing string literals with regular expressions never really works, at
least when they use backslash quoting. Python should have a standard
function to do this, written in C (maybe that's one of the things
kjbuckets does). Or Pyrex. Anyway, lacking that, writing such a thing
could be useful.
If the function works well enough, maybe it would be an incentive for
packages like MySQLdb to use ? placeholders as well. Ultimately that's
the solution that would work best for DBAPI as a whole.
Maybe create a DBAPI module again (didn't DBAPI 1 have a common module?)
-- put this function in there, the quote function, some common
exceptions for everyone to use. It'd be DBAPI 3.0, or 2.1... anyway,
that's a lot of the biggest problems people seem to have.
Ian
|