mirror of
https://github.com/django/django.git
synced 2025-10-24 06:06:09 +00:00
Revert "Fixed #16865 -- Made get_or_create use read database for initial get query."
Thanks to Jeremy Dunck for pointing out the problem with this change. If in a
single transaction, the master deletes a record and then get_or_creates a
similar record, under the new behavior the get_or_create would find the record
in the slave db and fail to re-create it, leaving the record nonexistent, which
violates the contract of get_or_create that the record should always exist
afterwards. We need to do everything against the master here in order to ensure
correctness.
This reverts commit 901af86550.
This commit is contained in:
@@ -64,27 +64,3 @@ 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)
|
||||
|
||||
Reference in New Issue
Block a user