[Django] #28682: QuerySet.update() : return the IDs of the matched rows

14 views
Skip to first unread message

Django

unread,
Oct 4, 2017, 3:05:28 PM10/4/17
to django-...@googlegroups.com
#28682: QuerySet.update() : return the IDs of the matched rows
-------------------------------------+-------------------------------------
Reporter: Дилян | Owner: nobody
Палаузов |
Type: | Status: new
Uncategorized |
Component: Database | Version: 1.11
layer (models, ORM) |
Severity: Normal | Keywords:
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
By coincidence all backends that can_return_ids_from_bulk_insert, which
happens to be only Postgresql, can also return ids from UPDATE:

UPDATE ... SET ... RETURNING id;

* update QuerySet.update() to return the PKs of the updated rows
* update the documentation of QuerySet.update(), stating the specific
return type for PG
* possibly rename can_return_ids_from_bulk_insert to can_return_ids or
can_return_anything(_from_select_insert_update_delete)?

--
Ticket URL: <https://code.djangoproject.com/ticket/28682>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Oct 5, 2017, 10:10:39 AM10/5/17
to django-...@googlegroups.com
#28682: QuerySet.update() : return the IDs of the matched rows
-------------------------------------+-------------------------------------
Reporter: Дилян Палаузов | Owner: nobody
Type: Uncategorized | Status: new
Component: Database layer | Version: 1.11
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by Дилян Палаузов:

Old description:

> By coincidence all backends that can_return_ids_from_bulk_insert, which
> happens to be only Postgresql, can also return ids from UPDATE:
>
> UPDATE ... SET ... RETURNING id;
>
> * update QuerySet.update() to return the PKs of the updated rows
> * update the documentation of QuerySet.update(), stating the specific
> return type for PG
> * possibly rename can_return_ids_from_bulk_insert to can_return_ids or
> can_return_anything(_from_select_insert_update_delete)?

New description:

By coincidence all backends that can_return_ids_from_bulk_insert, which
happens to be only Postgresql, can also return ids from UPDATE:

UPDATE ... SET ... RETURNING id;

* update QuerySet.update() to return the PKs of the updated rows
* update the documentation of QuerySet.update(), stating the specific
return type for PG
* possibly rename can_return_ids_from_bulk_insert to can_return_ids or
can_return_anything(_from_select_insert_update_delete)?

Like this:
{{{
diff --git a/django/db/models/sql/compiler.py
b/django/db/models/sql/compiler.py
--- a/django/db/models/sql/compiler.py
+++ b/django/db/models/sql/compiler.py
@@ -1230,11 +1230,11 @@ class SQLInsertCompiler(SQLCompiler):
else:
result.append("VALUES (%s)" % ",
".join(placeholder_rows[0]))
params = [param_rows[0]]
- col = "%s.%s" % (qn(opts.db_table), qn(opts.pk.column))
r_fmt, r_params = self.connection.ops.return_insert_id()
# Skip empty r_fmt to allow subclasses to customize behavior
for
# 3rd party backends. Refs #19096.
if r_fmt:
+ col = "%s.%s" % (qn(opts.db_table), qn(opts.pk.column))
result.append(r_fmt % col)
params += [r_params]
return [(" ".join(result),
tuple(chain.from_iterable(params)))]
@@ -1341,6 +1341,9 @@ class SQLUpdateCompiler(SQLCompiler):
where, params = self.compile(self.query.where)
if where:
result.append('WHERE %s' % where)
+ if self.connection.features.can_return_ids_from_bulk_insert:
+ opts = self.query.get_meta()
+ result.append("RETURNING %s.%s" % (qn(opts.db_table),
qn(opts.pk.column)))
return ' '.join(result), tuple(update_params + params)

def execute_sql(self, result_type):
@@ -1352,6 +1355,8 @@ class SQLUpdateCompiler(SQLCompiler):
"""
cursor = super().execute_sql(result_type)
try:
+ if self.connection.features.can_return_ids_from_bulk_insert:
# for Postgresql return the
+ return
self.connection.ops.fetch_returned_insert_ids(cursor) # PKs of the matched
columns
rows = cursor.rowcount if cursor else 0
is_empty = cursor is None
finally:
diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt
--- a/docs/ref/models/querysets.txt
+++ b/docs/ref/models/querysets.txt
@@ -2241,7 +2241,8 @@ retrieves the results and then checks if any were
returned.

Performs an SQL update query for the specified fields, and returns
the number of rows matched (which may not be equal to the number of rows
-updated if some rows already have the new value).
+updated if some rows already have the new value). On Postgresql it
returns
+instead a list with the primary keys of the matched rows.

For example, to turn comments off for all blog entries published in 2010,
you could do this::
}}}

--

--
Ticket URL: <https://code.djangoproject.com/ticket/28682#comment:1>

Django

unread,
Oct 5, 2017, 11:09:53 AM10/5/17
to django-...@googlegroups.com
#28682: Allow QuerySet.update() to return the IDs of the matched rows
-------------------------------------+-------------------------------------
Reporter: Дилян Палаузов | Owner: nobody
Type: New feature | Status: closed

Component: Database layer | Version: 1.11
(models, ORM) |
Severity: Normal | Resolution: wontfix
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tim Graham):

* status: new => closed
* resolution: => wontfix
* type: Uncategorized => New feature


Comment:

We can't change the return type of `QuerySet.update()` as proposed -- that
would be backwards incompatible and it would make writing code that works
across different databases more difficult. Perhaps #21461 would solve your
use case.

--
Ticket URL: <https://code.djangoproject.com/ticket/28682#comment:2>

Django

unread,
Mar 23, 2025, 8:16:22 PMMar 23
to django-...@googlegroups.com
#28682: Allow QuerySet.update() to return the IDs of the matched rows
-------------------------------------+-------------------------------------
Reporter: Дилян Палаузов | Owner: nobody
Type: New feature | Status: closed
Component: Database layer | Version: 1.11
(models, ORM) |
Severity: Normal | Resolution: wontfix
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Simon Charette):

Note that a more generic ticket to allow returning specified fields was
accepted in #32406 where
[https://code.djangoproject.com/ticket/32406#comment:23 a proposed
signature that maintains backward compatibility was proposed].
--
Ticket URL: <https://code.djangoproject.com/ticket/28682#comment:3>
Reply all
Reply to author
Forward
0 new messages