|
From: Magnus <ma...@th...> - 2003-05-28 09:53:31
|
Some parts of my reasoning below is more relevant to generic DB-API
than to SQLObject, I hope this is ok. (Tell me if I get boring.)
At 15:34 2003-05-27 -0500, Ian Bicking wrote:
>*If* those changes were made, then I'd feel much differently about using
>parameters. If you want to write up a PEP, to maybe take it past the
>discussion that's gone on for so long, then that'd be great, and I'd be
>happy to help proofread it or whatever... but it's really the authors of
>the database adapters who need convincing. Which may be easy, I don't
>know.
I doubt it :). The sqlite driver and the related PostgreSQL driver both
look for an attribute called '_quote', which I suppose they use for their
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 drivers?
Hopefully *someone* will like the idea. Maybe with a few more champions...=
:)
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... :)
>I would still disagree, at least for SQLObject. Or rather, I would say
>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.
My though was to allow .select("name=3D?", ("Guido's",)) as an alternative
to .select("name=3D'Guido''s'")
In cases like this you relieve a certain burden from the application
coder. That might be good, since you can (I suppose) write SQLObject
code without knowing a lot of SQL. I think it's easier to learn that
all literals are replaced with a '?' and that the actual values are
passed in a tuple, than to learn all about quoting and escaping.
It would also solve the MS Access date problem...
>Well, for instance, MySQL allows strings like 'that\'s it', which would
>break this. But it also allows 'that''s it', so maybe people will just
>have to use the one.
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 \'.
>I don't know how some databases treat things like " -- is "user?" a
>valid column name in Postgres?
Anyone using a questionmark in a table or column name in SQL should
be dragged to the square and shot in dawn, but I think the re can be
fixed to handle this as well.
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.
Is there a flaw in that strategy?
>I don't know... doing ad hoc SQL parsing
>seems like trouble to me. %s avoids that, since it doesn't do parsing.
On the other hand, it brings out other problems. I won't repeat what I
wrote on the db-sig.
>The other idea, like
>
>cursor.execute("INSERT INTO foo (bar, baz) VALUES (", foo, ", ", baz")")
>
>Would also work without doing parsing, even if it is a bit annoying.
I would hate that. There *is* a standard here, which is widely used
and I think it's reasonable to implement it both from performance,
maintenance and stability point of view. Why not use that?
Why not deprecate the %-operator in Python while we're at it. It
seems like a similar approach to me.
>Personally I don't mind %s at all -- so long as you aren't hardcoding
>string literals into your queries, having to quote % isn't that big a
>deal.
I think it's better to try to follow an established standard rather
than to invent a new one. My detailed knowledge is with SQL/92.
Both Dynamic SQL and the SQL CLI mandates ? for parameter passing.
The SQL standard does not enforce that an implementation provides
Dynamic or CLI. It's ok to only provide embedded SQL or the module
language, both of which use :name, but both of these standards allow
parameters to be passed in anywhere, as in:
"SELECT :col FROM :table WHERE :filter"
I.e. the :name syntax is according to the SQL standard not to be
quoted or escaped by the backend, but the ? parameters are, and
that's the way the Python DB-API standard requires. So the only
way to be complient with both SQL/92 and the Python DB-API is to
allow use of paramstyle qmark!
Obviously, we can use "SELECT %s FROM %s WHERE %s" and pass in
stuff with pythons %-operator to make our SQL even more dynamic,
but this is plain and simple Python string handling, and I think
it should be entirely explicit to the coder.
--
Magnus Lycka (It's really Lyckå), ma...@th...
Thinkware AB, Sweden, www.thinkware.se
I code Python ~ The shortest path from thought to working program=20
|