summaryrefslogtreecommitdiff
path: root/docs/topics/db/sql.txt
diff options
context:
space:
mode:
authorCarlton Gibson <carlton.gibson@noumenal.es>2023-02-09 16:48:46 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2023-02-10 21:12:06 +0100
commitb784768eef75afb32f6d2ce7166551a528bce0ec (patch)
treea375a57a50f1766538ea8a62ec49bda352d7f2b9 /docs/topics/db/sql.txt
parent4a89aa25c91e520c247aee428782274dcf10ffd0 (diff)
[4.2.x] Refs #34140 -- Applied rst code-block to non-Python examples.
Thanks to J.V. Zammit, Paolo Melchiorre, and Mariusz Felisiak for reviews. Backport of 534ac4829764f317cf2fbc4a18354fcc998c1425 from main.
Diffstat (limited to 'docs/topics/db/sql.txt')
-rw-r--r--docs/topics/db/sql.txt52
1 files changed, 39 insertions, 13 deletions
diff --git a/docs/topics/db/sql.txt b/docs/topics/db/sql.txt
index 93f7724774..6a76d5b0c8 100644
--- a/docs/topics/db/sql.txt
+++ b/docs/topics/db/sql.txt
@@ -56,7 +56,9 @@ This is best illustrated with an example. Suppose you have the following model::
last_name = models.CharField(...)
birth_date = models.DateField(...)
-You could then execute custom SQL like so::
+You could then execute custom SQL like so:
+
+.. code-block:: pycon
>>> for p in Person.objects.raw('SELECT * FROM myapp_person'):
... print(p)
@@ -104,7 +106,9 @@ Mapping query fields to model fields
``raw()`` automatically maps fields in the query to fields on the model.
The order of fields in your query doesn't matter. In other words, both
-of the following queries work identically::
+of the following queries work identically:
+
+.. code-block:: pycon
>>> Person.objects.raw('SELECT id, first_name, last_name, birth_date FROM myapp_person')
...
@@ -113,7 +117,9 @@ of the following queries work identically::
Matching is done by name. This means that you can use SQL's ``AS`` clauses to
map fields in the query to model fields. So if you had some other table that
-had ``Person`` data in it, you could easily map it into ``Person`` instances::
+had ``Person`` data in it, you could easily map it into ``Person`` instances:
+
+.. code-block:: pycon
>>> Person.objects.raw('''SELECT first AS first_name,
... last AS last_name,
@@ -126,7 +132,9 @@ As long as the names match, the model instances will be created correctly.
Alternatively, you can map fields in the query to model fields using the
``translations`` argument to ``raw()``. This is a dictionary mapping names of
fields in the query to names of fields on the model. For example, the above
-query could also be written::
+query could also be written:
+
+.. code-block:: pycon
>>> name_map = {'first': 'first_name', 'last': 'last_name', 'bd': 'birth_date', 'pk': 'id'}
>>> Person.objects.raw('SELECT * FROM some_other_table', translations=name_map)
@@ -135,26 +143,34 @@ Index lookups
-------------
``raw()`` supports indexing, so if you need only the first result you can
-write::
+write:
+
+.. code-block:: pycon
>>> first_person = Person.objects.raw('SELECT * FROM myapp_person')[0]
However, the indexing and slicing are not performed at the database level. If
you have a large number of ``Person`` objects in your database, it is more
-efficient to limit the query at the SQL level::
+efficient to limit the query at the SQL level:
+
+.. code-block:: pycon
>>> first_person = Person.objects.raw('SELECT * FROM myapp_person LIMIT 1')[0]
Deferring model fields
----------------------
-Fields may also be left out::
+Fields may also be left out:
+
+.. code-block:: pycon
>>> people = Person.objects.raw('SELECT id, first_name FROM myapp_person')
The ``Person`` objects returned by this query will be deferred model instances
(see :meth:`~django.db.models.query.QuerySet.defer()`). This means that the
-fields that are omitted from the query will be loaded on demand. For example::
+fields that are omitted from the query will be loaded on demand. For example:
+
+.. code-block:: pycon
>>> for p in Person.objects.raw('SELECT id, first_name FROM myapp_person'):
... print(p.first_name, # This will be retrieved by the original query
@@ -179,7 +195,9 @@ Adding annotations
You can also execute queries containing fields that aren't defined on the
model. For example, we could use `PostgreSQL's age() function`__ to get a list
-of people with their ages calculated by the database::
+of people with their ages calculated by the database:
+
+.. code-block:: pycon
>>> people = Person.objects.raw('SELECT *, age(birth_date) AS age FROM myapp_person')
>>> for p in people:
@@ -197,7 +215,9 @@ Passing parameters into ``raw()``
---------------------------------
If you need to perform parameterized queries, you can use the ``params``
-argument to ``raw()``::
+argument to ``raw()``:
+
+.. code-block:: pycon
>>> lname = 'Doe'
>>> Person.objects.raw('SELECT * FROM myapp_person WHERE last_name = %s', [lname])
@@ -218,13 +238,17 @@ replaced with parameters from the ``params`` argument.
**Do not use string formatting on raw queries or quote placeholders in your
SQL strings!**
- It's tempting to write the above query as::
+ It's tempting to write the above query as:
+
+ .. code-block:: pycon
>>> query = 'SELECT * FROM myapp_person WHERE last_name = %s' % lname
>>> Person.objects.raw(query)
You might also think you should write your query like this (with quotes
- around ``%s``)::
+ around ``%s``):
+
+ .. code-block:: pycon
>>> query = "SELECT * FROM myapp_person WHERE last_name = '%s'"
@@ -313,7 +337,9 @@ immutable and accessible by field names or indices, which might be useful::
nt_result = namedtuple('Result', [col[0] for col in desc])
return [nt_result(*row) for row in cursor.fetchall()]
-Here is an example of the difference between the three::
+Here is an example of the difference between the three:
+
+.. code-block:: pycon
>>> cursor.execute("SELECT id, parent_id FROM test LIMIT 2")
>>> cursor.fetchall()