I've been reading documentation for sqlite and found that many sources strongly recommend avoiding python string substitution in queries since it makes them vulnerable to injection attacks:
Avoid:
conn.execute("SELECT * FROM %s" % table_name)
conn.execute("SELECT * FROM {}".format(table_name))
I've seen several simple examples where string formatting like this is replaced with slqlite parameters:
values = ('my_table', '1')
conn.execute("SELECT * FROM ? WHERE ROWID = ?", values)
This works in the simple case, but fails when I want to retrieve the parameter values from a list as in this example:
Working code with string formatting:
c.execute("BEGIN TRANSACTION")
for i in range(len(amt_l)):
c.execute("""
INSERT INTO transactions ({}, {}, {}, {}, {})
VALUES ('{}', '{}', '{}', '{}', '{}')
""".format(header[0], header[1], header[2], header[3], header[4],
date_l[i], party_l[i], direction_l[i], ctr_party_l[i], amt_l[i]))
db.commit()
Non-working code using parameters:
c.execute("BEGIN TRANSACTION")
for i in range(len(amt_l)):
values = (header[0], header[1], header[2], header[3], header[4],
date_l[i], party_l[i], direction_l[i], ctr_party_l[i], amt_l[i])
c.execute("""
INSERT INTO transactions (?, ?, ?, ?, ?)
VALUES (?, ?, ?, ?, ?)
""", values)
Is there a way to use ?
to fill in parameters in the sql query when the parameter values are retrieved from a list?