On Sat, May 8, 2021 at 8:21 AM Richard Damon
On 5/7/21 5:56 PM, Nick Humrich wrote:
Marc,
You might have misunderstood me. I am not recommending sending the database raw strings without parameters, but rather that i-strings turn things into parameters and its impossible to mess up. Let me explain a little.
In sqlalchemy, you can use a format such as "update items set a=:value where id=:item_id" then you tell it the value of the parameters. SQLAlchemy then takes the :something part of the string and turns it into a parameter ($1, $2, etc). The problem being however, there is nothing stopping me from doing an f string on accident: f"update items set a={something} where id=:value". Because f-strings are eager, sqlalchemy cant protect you, you are now vulnerable to injection. But with i-strings, because they are not eager, it would actually know that you passed in the value as a variable, and turn it into a parameter. It knows the difference between the static part of the query and the dynamic part of the query, so it can actually protect you from yourself, or protect early engineers who don't even know what injection is.
Nick
I think the issue is what would the result of the i-string actually be? The database APIs want typically a string + a tuple or a dictionary, two seperate things. Are you suggesting that to use i-stings, all the API's need to be adjusted to accept some new type of object that is a string/dictionary combo?
That would be the case, yes. An i-string would have to return a single object (because every expression in Python is a single object), so anything that's expecting two parameters would need to learn how to handle that. That's a small consideration, though. People can always create their own small wrappers, eg: def sql(istring): return cursor.execute(istring.base, istring.vars) or something like that. And APIs can be enhanced over time, with i-string support being added to more things, same as Pathlib support has been progressively added. +1 on revisiting this. ChrisA