From: Daniele Varrazzo Date: Thu, 27 Nov 2025 01:49:09 +0000 (+0100) Subject: docs: add documentation for sql.as_string() and as_bytes() functions X-Git-Tag: 3.3.0~6^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=492a6e0519cf3964321f38588e5b6b367790bfb8;p=thirdparty%2Fpsycopg.git docs: add documentation for sql.as_string() and as_bytes() functions --- diff --git a/docs/api/sql.rst b/docs/api/sql.rst index 86e1a40e8..e8ca6246d 100644 --- a/docs/api/sql.rst +++ b/docs/api/sql.rst @@ -163,10 +163,18 @@ The `!sql` objects are in the following inheritance hierarchy: Utility functions ----------------- -.. autofunction:: quote +.. autofunction:: as_string + + .. versionadded:: 3.3 + +.. autofunction:: as_bytes + + .. versionadded:: 3.3 .. data:: NULL DEFAULT `sql.SQL` objects often useful in queries. + +.. autofunction:: quote diff --git a/docs/basic/tstrings.rst b/docs/basic/tstrings.rst index 02280451c..15d5413e8 100644 --- a/docs/basic/tstrings.rst +++ b/docs/basic/tstrings.rst @@ -53,6 +53,17 @@ but has a clear readability advantage because the Python variable names or expressions appear directly in the place where they will be used in the query (no more forgetting to add a placeholder when adding a field in an INSERT...). +If you want to convert the template string to a regular string, instead of +executing it directly, you can use the `sql.as_string()` or `~sql.as_bytes()` +functions: + +.. code:: python + + >>> name = "O'Reilly" + >>> dob = datetime.date(1970, 1, 1) + >>> print(sql.as_string(t"INSERT INTO tbl VALUES ({name}, {dob})")) + INSERT INTO tbl VALUES ('O''Reilly', '1970-01-01'::date) + With template strings it is also easy to parametrize parts of the query other than parameter values, for example tables or fields names: diff --git a/psycopg/psycopg/_tstrings.py b/psycopg/psycopg/_tstrings.py index e3056b115..90b1b3e22 100644 --- a/psycopg/psycopg/_tstrings.py +++ b/psycopg/psycopg/_tstrings.py @@ -143,6 +143,10 @@ class TemplateProcessor: def as_string(t: Template, context: abc.AdaptContext | None = None) -> str: + """Convert a template string to a string. + + This function is exposed as part of psycopg.sql.as_string(). + """ tx = Transformer(context) tp = TemplateProcessor(t, tx=tx, server_params=False) tp.process() @@ -150,6 +154,10 @@ def as_string(t: Template, context: abc.AdaptContext | None = None) -> str: def as_bytes(t: Template, context: abc.AdaptContext | None = None) -> bytes: + """Convert a template string to a bytes string. + + This function is exposed as part of psycopg.sql.as_bytes(). + """ tx = Transformer(context) tp = TemplateProcessor(t, tx=tx, server_params=False) tp.process() diff --git a/psycopg/psycopg/sql.py b/psycopg/psycopg/sql.py index 088ebacb7..152e3f499 100644 --- a/psycopg/psycopg/sql.py +++ b/psycopg/psycopg/sql.py @@ -506,6 +506,24 @@ DEFAULT = SQL("DEFAULT") def as_string(obj: Any, context: AdaptContext | None = None) -> str: + """Convert an object to a string according to SQL rules. + + :param obj: the object to convert + :param context: the context in which to convert the object + :type context: `~psycopg.abc.AdaptContext` | `!None` + + Adaptation happens according to the type of `!obj`: + + - `Composable` objects are converted according to their + `~Composable.as_string()` method; + - `~string.templatelib.Template` strings are converted according to the + rules documented in :ref:`template-strings`; + - every other object is converted as it was :ref:`a parameter passed to a + query `. + + If `!context` is specified then it is be used to customize the conversion. + for example using the encoding of a connection or the dumpers registered. + """ if isinstance(obj, Composable): return obj.as_string(context=context) elif isinstance(obj, Template): @@ -517,6 +535,14 @@ def as_string(obj: Any, context: AdaptContext | None = None) -> str: def as_bytes(obj: Any, context: AdaptContext | None = None) -> bytes: + """Convert an object to a bytes string according to SQL rules. + + :param obj: the object to convert + :param context: the context in which to convert the object + :type context: `~psycopg.abc.AdaptContext` | `!None` + + See `as_string()` for details. + """ if isinstance(obj, Composable): return obj.as_bytes(context=context) elif isinstance(obj, Template):