Given a string with bindings:
input = "SELECT * FROM table WHERE col1 = %s AND col2 = %(col2_value)s"
I want to convert %s
to ?
and %(named)s
to @named
, such that I get:
input = "SELECT * FROM table WHERE col1 = ? AND col2 = @col2_value"
My current implementation uses re
to swap the two types and return the list of bindings:
def _convert_bindings(query: str) -> Tuple[str, List[Union[None, str]]]:
pos_rex = r"%s"
named_rex = r"%\((\w+)\)s"
bindings = [
None if m.string == "%s" else re.search(r"%\((?P<name>\w+)\)s", m.string).group("name")
for m in re.finditer(f"{pos_rex}|{named_rex}", query)
]
sql = re.sub(pos_rex, r"?", query)
sql = re.sub(named_rex, r"@\1", query)
return sql, bindings
But I figured Python must have a builtin way to find & replace parameters, since str.format
does it already.
So what's the most pythonic way to extract %s
and %(named)s
, and subsequently replace them? Is there a function/property that could be named something like "str.params" or a function getparams from a builtin module?
Assume no prior knowledge of the list of named parameters.