[BangPypers] sql query parameters
Carl Karsten
carl at personnelware.com
Sat Oct 10 18:32:01 CEST 2009
On Sat, Oct 10, 2009 at 10:05 AM, Noufal Ibrahim <noufal at gmail.com> wrote:
> On Sat, Oct 10, 2009 at 7:59 PM, Carl Karsten <carl at personnelware.com> wrote:
> [..]
>> I need to inject...
>>
>> The line should be:
>>
>> cursor.execute(query, ('burger', '2009-09-10 12:00:00'))
>
> Ah. Then it's just a case of the API doing the quoting internally
> which points to a better API than a better language.
Hopefully [1] it is not "quoting", for reasonable definitions of
quoting. "serializing" maybe, but in the case of sqlite, which
executes in the same memory space as python, I am not sure the data is
even serialized.
This is described in the sql92 spec:
""" Many SQL-statements can be written to use "parameters" (which are
manifested in static execution of SQL-statements as <parameters>
in <SQL statement>s contained in <procedure>s in <module>s or as
<embedded variable name>s in <SQL statement>s contained in <em-
bedded SQL host program>s). In SQL-statements that are executed
dynamically, the parameters are called dynamic parameters (<dynamic
parameter specification>s) and are represented in SQL language by a
<question mark> (?).
""" http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt
Perhaps some code showing both sides of the connection will clarify:
db=[
{'a':'x', 'b':2, 'c':3},
{'a':'y', 'b':5, 'c':6},
{'a':'z', 'b':8, 'c':9},
]
def whack():
db=[]
print "blam-o!"
def server(command, parameters=() ):
"""
command is something like "find b=5"
"""
def whack():
db=[]
print "blam-o!"
print "parsing", command.__repr__()
words=command.split()
if words[0]=='find':
expression = words[1]
print "1 finding", expression.__repr__()
field,value = expression.split('=')
print "2 finding", field, value.__repr__()
if value=='?':
value=parameters[0]
else:
value = eval(value)
print "3 finding", field, value.__repr__()
rows = [ row for row in db if row[field]==value]
print "found ", rows
return rows
server("find a='y'")
server("find a=?",('y',))
server("find b=8")
server("find b=?",(8,))
server("find c=?",('whack()',))
server("find c=wh1ack()")
The critical part:
if value=='?':
value=parameters[0]
else:
value = eval(value)
value=parameters[0] is very light weight. the data is already in the
correct data type
eval(value) is cpu intensive, and as the last line shows, subject to injection.
yes, this is a contrived example, but it does a pretty good job
demonstrating the 2 ways of getting values to the server. It does not
at all demonstrate the query optimization caching stuff, but I have no
clue how to show that in something this simple.
--
Carl K
More information about the BangPypers
mailing list