Loading django/db/models/query.py +1 −1 Original line number Diff line number Diff line Loading @@ -455,9 +455,9 @@ class QuerySet(object): if f.attname in lookup: lookup[f.name] = lookup.pop(f.attname) try: self._for_write = True return self.get(**lookup), False except self.model.DoesNotExist: self._for_write = True try: params = dict([(k, v) for k, v in kwargs.items() if '__' not in k]) params.update(defaults) Loading docs/releases/1.5.txt +9 −0 Original line number Diff line number Diff line Loading @@ -338,6 +338,15 @@ Miscellaneous needs. The new default value is `0666` (octal) and the current umask value is first masked out. * In a multi-database situation, ``get_or_create()`` will now use a read database for the initial ``get`` attempt (previously, it used only the write database for all queries). This change reduces load on the write (master) database, in exchange for slightly more frequent false-negatives on the initial ``get`` due to replication lag. In those cases the subsequent insert will still go to the master and fail, after which the existing object will be fetched from the master. Features deprecated in 1.5 ========================== Loading tests/modeltests/get_or_create/tests.py +24 −0 Original line number Diff line number Diff line Loading @@ -64,3 +64,27 @@ class GetOrCreateTests(TestCase): formatted_traceback = traceback.format_exc() self.assertIn('obj.save', formatted_traceback) def test_initial_get_on_read_db(self): """ get_or_create should only set _for_write when it's actually doing a create action. This makes sure that the initial .get() will be able to use a slave database. Specially when some form of database pinning is in place this will help to not put all the SELECT queries on the master. Refs #16865. """ qs = Person.objects.get_query_set() p, created = qs.get_or_create( first_name="Stuart", last_name="Sutcliffe", defaults={ "birthday": date(1940, 6, 23), } ) self.assertTrue(created) self.assertTrue(qs._for_write) qs = Person.objects.get_query_set() p, created = qs.get_or_create( first_name="Stuart", last_name="Sutcliffe") self.assertFalse(created) self.assertFalse(qs._for_write) Loading
django/db/models/query.py +1 −1 Original line number Diff line number Diff line Loading @@ -455,9 +455,9 @@ class QuerySet(object): if f.attname in lookup: lookup[f.name] = lookup.pop(f.attname) try: self._for_write = True return self.get(**lookup), False except self.model.DoesNotExist: self._for_write = True try: params = dict([(k, v) for k, v in kwargs.items() if '__' not in k]) params.update(defaults) Loading
docs/releases/1.5.txt +9 −0 Original line number Diff line number Diff line Loading @@ -338,6 +338,15 @@ Miscellaneous needs. The new default value is `0666` (octal) and the current umask value is first masked out. * In a multi-database situation, ``get_or_create()`` will now use a read database for the initial ``get`` attempt (previously, it used only the write database for all queries). This change reduces load on the write (master) database, in exchange for slightly more frequent false-negatives on the initial ``get`` due to replication lag. In those cases the subsequent insert will still go to the master and fail, after which the existing object will be fetched from the master. Features deprecated in 1.5 ========================== Loading
tests/modeltests/get_or_create/tests.py +24 −0 Original line number Diff line number Diff line Loading @@ -64,3 +64,27 @@ class GetOrCreateTests(TestCase): formatted_traceback = traceback.format_exc() self.assertIn('obj.save', formatted_traceback) def test_initial_get_on_read_db(self): """ get_or_create should only set _for_write when it's actually doing a create action. This makes sure that the initial .get() will be able to use a slave database. Specially when some form of database pinning is in place this will help to not put all the SELECT queries on the master. Refs #16865. """ qs = Person.objects.get_query_set() p, created = qs.get_or_create( first_name="Stuart", last_name="Sutcliffe", defaults={ "birthday": date(1940, 6, 23), } ) self.assertTrue(created) self.assertTrue(qs._for_write) qs = Person.objects.get_query_set() p, created = qs.get_or_create( first_name="Stuart", last_name="Sutcliffe") self.assertFalse(created) self.assertFalse(qs._for_write)