diff options
author | Anssi Kääriäinen <akaariai@gmail.com> | 2013-08-30 09:41:07 +0300 |
---|---|---|
committer | Anssi Kääriäinen <akaariai@gmail.com> | 2013-08-30 09:47:34 +0300 |
commit | 76e38a21777243fec58c640d617bb71a251c5ba1 (patch) | |
tree | 5a14a0f8c788649a97fffac96ed487c853fee603 /docs | |
parent | cd10e998b6a8f9daaf2e25cad55f33f3df51ea88 (diff) | |
download | django-76e38a21777243fec58c640d617bb71a251c5ba1.tar.gz |
[1.6.x] Fixed #20988 -- Added model meta option select_on_save
The option can be used to force pre 1.6 style SELECT on save behaviour.
This is needed in case the database returns zero updated rows even if
there is a matching row in the DB. One such case is PostgreSQL update
trigger that returns NULL.
Reviewed by Tim Graham.
Refs #16649
Backport of e973ee6a9879969b8ae05bb7ff681172cc5386a5 from master
Conflicts:
django/db/models/options.py
tests/basic/tests.py
Diffstat (limited to 'docs')
-rw-r--r-- | docs/ref/models/instances.txt | 17 | ||||
-rw-r--r-- | docs/ref/models/options.txt | 22 | ||||
-rw-r--r-- | docs/releases/1.6.txt | 20 |
3 files changed, 50 insertions, 9 deletions
diff --git a/docs/ref/models/instances.txt b/docs/ref/models/instances.txt index 4bb6af2a51..ce943f141d 100644 --- a/docs/ref/models/instances.txt +++ b/docs/ref/models/instances.txt @@ -305,16 +305,23 @@ follows this algorithm: * If the object's primary key attribute is *not* set or if the ``UPDATE`` didn't update anything, Django executes an ``INSERT``. -.. versionchanged:: 1.6 - - Previously Django used ``SELECT`` - if not found ``INSERT`` else ``UPDATE`` - algorithm. The old algorithm resulted in one more query in ``UPDATE`` case. - The one gotcha here is that you should be careful not to specify a primary-key value explicitly when saving new objects, if you cannot guarantee the primary-key value is unused. For more on this nuance, see `Explicitly specifying auto-primary-key values`_ above and `Forcing an INSERT or UPDATE`_ below. +.. versionchanged:: 1.6 + + Previously Django did a ``SELECT`` when the primary key attribute was set. + If the ``SELECT`` found a row, then Django did an ``UPDATE``, otherwise it + did an ``INSERT``. The old algorithm results in one more query in the + ``UPDATE`` case. There are some rare cases where the database doesn't + report that a row was updated even if the database contains a row for the + object's primary key value. An example is the PostgreSQL ``ON UPDATE`` + trigger which returns ``NULL``. In such cases it is possible to revert to the + old algorithm by setting the :attr:`~django.db.models.Options.select_on_save` + option to ``True``. + .. _ref-models-force-insert: Forcing an INSERT or UPDATE diff --git a/docs/ref/models/options.txt b/docs/ref/models/options.txt index 6944796ef1..9c58416e12 100644 --- a/docs/ref/models/options.txt +++ b/docs/ref/models/options.txt @@ -238,6 +238,28 @@ Django quotes column and table names behind the scenes. If ``proxy = True``, a model which subclasses another model will be treated as a :ref:`proxy model <proxy-models>`. +``select_on_save`` +------------------ + +.. attribute:: Options.select_on_save + + .. versionadded:: 1.6 + + Determines if Django will use the pre-1.6 + :meth:`django.db.models.Model.save()` algorithm. The old algorithm + uses ``SELECT`` to determine if there is an existing row to be updated. + The new algorith tries an ``UPDATE`` directly. In some rare cases the + ``UPDATE`` of an existing row isn't visible to Django. An example is the + PostgreSQL ``ON UPDATE`` trigger which returns ``NULL``. In such cases the + new algorithm will end up doing an ``INSERT`` even when a row exists in + the database. + + Usually there is no need to set this attribute. The default is + ``False``. + + See :meth:`django.db.models.Model.save()` for more about the old and + new saving algorithm. + ``unique_together`` ------------------- diff --git a/docs/releases/1.6.txt b/docs/releases/1.6.txt index 105e302b7d..3903aa403f 100644 --- a/docs/releases/1.6.txt +++ b/docs/releases/1.6.txt @@ -138,6 +138,22 @@ A :djadmin:`check` management command was added, enabling you to verify if your current configuration (currently oriented at settings) is compatible with the current version of Django. +:meth:`Model.save() <django.db.models.Model.save()>` algorithm changed +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The :meth:`Model.save() <django.db.models.Model.save()>` method now +tries to directly ``UPDATE`` the database if the instance has a primary +key value. Previously ``SELECT`` was performed to determine if ``UPDATE`` +or ``INSERT`` were needed. The new algorithm needs only one query for +updating an existing row while the old algorithm needed two. See +:meth:`Model.save() <django.db.models.Model.save()>` for more details. + +In some rare cases the database doesn't report that a matching row was +found when doing an ``UPDATE``. An example is the PostgreSQL ``ON UPDATE`` +trigger which returns ``NULL``. In such cases it is possible to set +:attr:`django.db.models.Options.select_on_save` flag to force saving to +use the old algorithm. + Minor features ~~~~~~~~~~~~~~ @@ -222,10 +238,6 @@ Minor features * Generic :class:`~django.contrib.gis.db.models.GeometryField` is now editable with the OpenLayers widget in the admin. -* The :meth:`Model.save() <django.db.models.Model.save()>` will do - ``UPDATE`` - if not updated - ``INSERT`` instead of ``SELECT`` - if not - found ``INSERT`` else ``UPDATE`` in case the model's primary key is set. - * The documentation contains a :doc:`deployment checklist </howto/deployment/checklist>`. |