Merge `Composable` objects into a template. :param args: parameters to replace to numbered (``{0}``, ``{1}``) or auto-numbered (``{}``) placeholders :param kwargs: parameters to replace to named (``{name}``) placeholders :return: the union of the `!SQL`
(self, *args: Any, **kwargs: Any)
| 218 | return self._obj.encode(enc) |
| 219 | |
| 220 | def format(self, *args: Any, **kwargs: Any) -> Composed: |
| 221 | """ |
| 222 | Merge `Composable` objects into a template. |
| 223 | |
| 224 | :param args: parameters to replace to numbered (``{0}``, ``{1}``) or |
| 225 | auto-numbered (``{}``) placeholders |
| 226 | :param kwargs: parameters to replace to named (``{name}``) placeholders |
| 227 | :return: the union of the `!SQL` string with placeholders replaced |
| 228 | :rtype: `Composed` |
| 229 | |
| 230 | The method is similar to the Python `str.format()` method: the string |
| 231 | template supports auto-numbered (``{}``), numbered (``{0}``, |
| 232 | ``{1}``...), and named placeholders (``{name}``), with positional |
| 233 | arguments replacing the numbered placeholders and keywords replacing |
| 234 | the named ones. However placeholder modifiers (``{0!r}``, ``{0:<10}``) |
| 235 | are not supported. |
| 236 | |
| 237 | If a `!Composable` objects is passed to the template it will be merged |
| 238 | according to its `as_string()` method. If any other Python object is |
| 239 | passed, it will be wrapped in a `Literal` object and so escaped |
| 240 | according to SQL rules. |
| 241 | |
| 242 | Example:: |
| 243 | |
| 244 | >>> print(sql.SQL("SELECT * FROM {} WHERE {} = %s") |
| 245 | ... .format(sql.Identifier('people'), sql.Identifier('id')) |
| 246 | ... .as_string(conn)) |
| 247 | SELECT * FROM "people" WHERE "id" = %s |
| 248 | |
| 249 | >>> print(sql.SQL("SELECT * FROM {tbl} WHERE name = {name}") |
| 250 | ... .format(tbl=sql.Identifier('people'), name="O'Rourke")) |
| 251 | ... .as_string(conn)) |
| 252 | SELECT * FROM "people" WHERE name = 'O''Rourke' |
| 253 | |
| 254 | """ |
| 255 | rv: list[Composable] = [] |
| 256 | autonum: int | None = 0 |
| 257 | # TODO: this is probably not the right way to whitelist pre |
| 258 | # pyre complains. Will wait for mypy to complain too to fix. |
| 259 | pre: LiteralString |
| 260 | for pre, name, spec, conv in self._formatter.parse(self._obj): |
| 261 | if spec: |
| 262 | raise ValueError("no format specification supported by SQL") |
| 263 | if conv: |
| 264 | raise ValueError("no format conversion supported by SQL") |
| 265 | if pre: |
| 266 | rv.append(SQL(pre)) |
| 267 | |
| 268 | if name is None: |
| 269 | continue |
| 270 | |
| 271 | if name.isdigit(): |
| 272 | if autonum: |
| 273 | raise ValueError( |
| 274 | "cannot switch from automatic field numbering to manual" |
| 275 | ) |
| 276 | rv.append(args[int(name)]) |
| 277 | autonum = None |