Ticket #16649: save_adding_hint.diff

File save_adding_hint.diff, 2.1 KB (added by akaariai, 4 years ago)

When saving, choose between select or update path based on model._state

  • django/db/models/base.py

    diff --git a/django/db/models/base.py b/django/db/models/base.py
    index b01bb0e..2e6bea8 100644
    a b class ModelState(object): 
    269269        self.db = db
    270270        # If true, uniqueness validation checks will consider this a new, as-yet-unsaved object.
    271271        # Necessary for correct validation of new instances of objects with explicit (non-auto) PKs.
    272         # This impacts validation only; it has no effect on the actual save.
     272        # This impacts validation and it is also used as a hint when saving. See save_base for
     273        # details.
    273274        self.adding = True
    274275
    275276class Model(object):
    class Model(object): 
    514515
    515516        if not meta.proxy:
    516517            non_pks = [f for f in meta.local_fields if not f.primary_key]
    517 
    518518            pk_val = self._get_pk_val(meta)
    519519            pk_set = pk_val is not None
    520520            record_exists = False
    521521            manager = cls._base_manager
     522            # A small optimization: when we expect that the object does not exist in the
     523            # db we will not do the normal update - if nothing update - save dance.
     524            # Instead we do the old way of select - insert or update. This is because
     525            # when saving large models we need to transfer the data in the update which
     526            # will do nothing and then again in the insert. The select is faster when
     527            # insert is expected.
     528            # However, if force_insert or force_update is set, we naturally do not
     529            # override them.
     530            if not force_insert and not force_update:
     531                if pk_set and non_pks and (self._state.db <> using or self._state.adding):
     532                    if manager.using(using).filter(pk=pk_val).exists():
     533                        force_update = True
     534                    else:
     535                        force_insert = True
    522536            if pk_set and not force_insert:
    523537                # Try to update the object. If something is updated, we know the record
    524538                # existed. If not, we know it did not exists.
Back to Top