mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-26 02:43:43 +03:00
More doc love for the sql module
This commit is contained in:
parent
9926942260
commit
49461c2c39
|
@ -151,6 +151,24 @@ Psycopg converts :sql:`json` values into Python objects but :sql:`jsonb` values
|
||||||
See :ref:`adapt-json` for further details.
|
See :ref:`adapt-json` for further details.
|
||||||
|
|
||||||
|
|
||||||
|
.. _faq-identifier:
|
||||||
|
.. cssclass:: faq
|
||||||
|
|
||||||
|
How can I pass field/table names to a query?
|
||||||
|
The arguments in the `~cursor.execute()` methods can only represent data
|
||||||
|
to pass to the query: they cannot represent a table or field name::
|
||||||
|
|
||||||
|
# This doesn't work
|
||||||
|
cur.execute("insert into %s values (%s)", ["my_table", 42])
|
||||||
|
|
||||||
|
If you want to build a query dynamically you can use the objects exposed
|
||||||
|
by the `psycopg2.sql` module::
|
||||||
|
|
||||||
|
cur.execute(
|
||||||
|
sql.SQL("insert into %s values (%%s)") % [sql.Identifier("my_table")],
|
||||||
|
[42])
|
||||||
|
|
||||||
|
|
||||||
.. _faq-bytea-9.0:
|
.. _faq-bytea-9.0:
|
||||||
.. cssclass:: faq
|
.. cssclass:: faq
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
The module contains objects and functions useful to generate SQL dynamically,
|
The module contains objects and functions useful to generate SQL dynamically,
|
||||||
in a convenient and safe way. SQL identifiers (e.g. names of tables and
|
in a convenient and safe way. SQL identifiers (e.g. names of tables and
|
||||||
fields) cannot be passed to the `~cursor.execute()` function like query
|
fields) cannot be passed to the `~cursor.execute()` method like query
|
||||||
arguments::
|
arguments::
|
||||||
|
|
||||||
# This will not work
|
# This will not work
|
||||||
|
@ -45,7 +45,7 @@ in the presence of a table or field name with containing characters to escape,
|
||||||
or will present a potentially exploitable weakness.
|
or will present a potentially exploitable weakness.
|
||||||
|
|
||||||
The objects exposed by the `!psycopg2.sql` module allow generating SQL
|
The objects exposed by the `!psycopg2.sql` module allow generating SQL
|
||||||
statements on the fly, separating clearly the variable parts in the statement
|
statements on the fly, separating clearly the variable parts of the statement
|
||||||
from the query parameters::
|
from the query parameters::
|
||||||
|
|
||||||
from psycopg2 import sql
|
from psycopg2 import sql
|
||||||
|
|
|
@ -132,9 +132,10 @@ query:
|
||||||
>>> cur.execute("INSERT INTO foo VALUES (%s)", ("bar",)) # correct
|
>>> cur.execute("INSERT INTO foo VALUES (%s)", ("bar",)) # correct
|
||||||
>>> cur.execute("INSERT INTO foo VALUES (%s)", ["bar"]) # correct
|
>>> cur.execute("INSERT INTO foo VALUES (%s)", ["bar"]) # correct
|
||||||
|
|
||||||
- Only variable values should be bound via this method: it shouldn't be used
|
- Only query values should be bound via this method: it shouldn't be used to
|
||||||
to set table or field names. For these elements, ordinary string formatting
|
merge table or field names to the query. If you need to generate dynamically
|
||||||
should be used before running `~cursor.execute()`.
|
an SQL query (for instance choosing dynamically a table name) you can use
|
||||||
|
the facilities provided by the `psycopg2.sql` module.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
58
lib/sql.py
58
lib/sql.py
|
@ -78,9 +78,10 @@ class Composed(Composable):
|
||||||
|
|
||||||
Example::
|
Example::
|
||||||
|
|
||||||
>>> sql.Composed([sql.SQL("insert into "), sql.Identifier("table")]) \\
|
>>> comp = sql.Composed(
|
||||||
... .as_string(conn)
|
... [sql.SQL("insert into "), sql.Identifier("table")])
|
||||||
'insert into "table"'
|
>>> print(comp.as_string(conn))
|
||||||
|
insert into "table"
|
||||||
|
|
||||||
.. automethod:: join
|
.. automethod:: join
|
||||||
"""
|
"""
|
||||||
|
@ -119,8 +120,8 @@ class Composed(Composable):
|
||||||
Example::
|
Example::
|
||||||
|
|
||||||
>>> fields = sql.Identifier('foo') + sql.Identifier('bar') # a Composed
|
>>> fields = sql.Identifier('foo') + sql.Identifier('bar') # a Composed
|
||||||
>>> fields.join(', ').as_string(conn)
|
>>> print(fields.join(', ').as_string(conn))
|
||||||
'"foo", "bar"'
|
"foo", "bar"
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if isinstance(joiner, basestring):
|
if isinstance(joiner, basestring):
|
||||||
|
@ -155,9 +156,8 @@ class SQL(Composable):
|
||||||
>>> query = sql.SQL("select %s from %s") % [
|
>>> query = sql.SQL("select %s from %s") % [
|
||||||
... sql.SQL(', ').join([sql.Identifier('foo'), sql.Identifier('bar')]),
|
... sql.SQL(', ').join([sql.Identifier('foo'), sql.Identifier('bar')]),
|
||||||
... sql.Identifier('table')]
|
... sql.Identifier('table')]
|
||||||
>>> query.as_string(conn)
|
>>> print(query.as_string(conn))
|
||||||
select "foo", "bar" from "table"'
|
select "foo", "bar" from "table"
|
||||||
|
|
||||||
|
|
||||||
.. automethod:: join
|
.. automethod:: join
|
||||||
"""
|
"""
|
||||||
|
@ -184,8 +184,8 @@ class SQL(Composable):
|
||||||
Example::
|
Example::
|
||||||
|
|
||||||
>>> snip - sql.SQL(', ').join(map(sql.Identifier, ['foo', 'bar', 'baz']))
|
>>> snip - sql.SQL(', ').join(map(sql.Identifier, ['foo', 'bar', 'baz']))
|
||||||
>>> snip.as_string(conn)
|
>>> print(snip.as_string(conn))
|
||||||
'"foo", "bar", "baz"'
|
"foo", "bar", "baz"
|
||||||
"""
|
"""
|
||||||
if isinstance(seq, Composed):
|
if isinstance(seq, Composed):
|
||||||
seq = seq._seq
|
seq = seq._seq
|
||||||
|
@ -214,6 +214,15 @@ class Identifier(Composable):
|
||||||
|
|
||||||
.. __: https://www.postgresql.org/docs/current/static/sql-syntax-lexical.html# \
|
.. __: https://www.postgresql.org/docs/current/static/sql-syntax-lexical.html# \
|
||||||
SQL-SYNTAX-IDENTIFIERS
|
SQL-SYNTAX-IDENTIFIERS
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
>>> t1 = sql.Identifier("foo")
|
||||||
|
>>> t2 = sql.Identifier("ba'r")
|
||||||
|
>>> t3 = sql.Identifier('ba"z')
|
||||||
|
>>> print(sql.SQL(', ').join([t1, t2, t3]).as_string(conn))
|
||||||
|
"foo", "ba'r", "ba""z"
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, string):
|
def __init__(self, string):
|
||||||
if not isinstance(string, basestring):
|
if not isinstance(string, basestring):
|
||||||
|
@ -239,6 +248,14 @@ class Literal(Composable):
|
||||||
The string returned by `!as_string()` follows the normal :ref:`adaptation
|
The string returned by `!as_string()` follows the normal :ref:`adaptation
|
||||||
rules <python-types-adaptation>` for Python objects.
|
rules <python-types-adaptation>` for Python objects.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
>>> s1 = sql.Literal("foo")
|
||||||
|
>>> s2 = sql.Literal("ba'r")
|
||||||
|
>>> s3 = sql.Literal(42)
|
||||||
|
>>> print(sql.SQL(', ').join([s1, s2, s3]).as_string(conn))
|
||||||
|
'foo', 'ba''r', 42
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, wrapped):
|
def __init__(self, wrapped):
|
||||||
self._wrapped = wrapped
|
self._wrapped = wrapped
|
||||||
|
@ -277,17 +294,20 @@ class Placeholder(Composable):
|
||||||
|
|
||||||
Examples::
|
Examples::
|
||||||
|
|
||||||
>>> (sql.SQL("insert into table (%s) values (%s)") % [
|
>>> names = ['foo', 'bar', 'baz']
|
||||||
... sql.SQL(', ').join(map(sql.Identifier, names)),
|
|
||||||
... sql.SQL(', ').join(sql.Placeholder() * 3)
|
|
||||||
... ]).as_string(conn)
|
|
||||||
'insert into table ("foo", "bar", "baz") values (%s, %s, %s)'
|
|
||||||
|
|
||||||
>>> (sql.SQL("insert into table (%s) values (%s)") % [
|
>>> q1 = sql.SQL("insert into table (%s) values (%s)") % [
|
||||||
... sql.SQL(', ').join(map(sql.Identifier, names)),
|
... sql.SQL(', ').join(map(sql.Identifier, names)),
|
||||||
... sql.SQL(', ').join(map(sql.Placeholder, names))
|
... sql.SQL(', ').join(sql.Placeholder() * 3)]
|
||||||
... ]).as_string(conn)
|
>>> print(q1.as_string(conn))
|
||||||
'insert into table ("foo", "bar", "baz") values (%(foo)s, %(bar)s, %(baz)s)'
|
insert into table ("foo", "bar", "baz") values (%s, %s, %s)
|
||||||
|
|
||||||
|
>>> q2 = sql.SQL("insert into table (%s) values (%s)") % [
|
||||||
|
... sql.SQL(', ').join(map(sql.Identifier, names)),
|
||||||
|
... sql.SQL(', ').join(map(sql.Placeholder, names))]
|
||||||
|
>>> print(q2.as_string(conn))
|
||||||
|
insert into table ("foo", "bar", "baz") values (%(foo)s, %(bar)s, %(baz)s)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, name=None):
|
def __init__(self, name=None):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user