mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	Fixed #20761 -- Fixed DatabaseError handling in get_or_create and update_or_create.
This commit is contained in:
		| @@ -8,7 +8,7 @@ import sys | |||||||
|  |  | ||||||
| from django.conf import settings | from django.conf import settings | ||||||
| from django.core import exceptions | from django.core import exceptions | ||||||
| from django.db import connections, router, transaction, DatabaseError | from django.db import connections, router, transaction, DatabaseError, IntegrityError | ||||||
| from django.db.models.constants import LOOKUP_SEP | from django.db.models.constants import LOOKUP_SEP | ||||||
| from django.db.models.fields import AutoField | from django.db.models.fields import AutoField | ||||||
| from django.db.models.query_utils import (Q, select_related_descend, | from django.db.models.query_utils import (Q, select_related_descend, | ||||||
| @@ -397,34 +397,35 @@ class QuerySet(object): | |||||||
|                 return obj, created |                 return obj, created | ||||||
|         for k, v in six.iteritems(filtered_defaults): |         for k, v in six.iteritems(filtered_defaults): | ||||||
|             setattr(obj, k, v) |             setattr(obj, k, v) | ||||||
|  |  | ||||||
|  |         sid = transaction.savepoint(using=self.db) | ||||||
|         try: |         try: | ||||||
|             sid = transaction.savepoint(using=self.db) |  | ||||||
|             obj.save(update_fields=filtered_defaults.keys(), using=self.db) |             obj.save(update_fields=filtered_defaults.keys(), using=self.db) | ||||||
|             transaction.savepoint_commit(sid, using=self.db) |             transaction.savepoint_commit(sid, using=self.db) | ||||||
|             return obj, False |             return obj, False | ||||||
|         except DatabaseError: |         except DatabaseError: | ||||||
|             transaction.savepoint_rollback(sid, using=self.db) |             transaction.savepoint_rollback(sid, using=self.db) | ||||||
|             six.reraise(sys.exc_info()) |             six.reraise(*sys.exc_info()) | ||||||
|  |  | ||||||
|     def _create_object_from_params(self, lookup, params): |     def _create_object_from_params(self, lookup, params): | ||||||
|         """ |         """ | ||||||
|         Tries to create an object using passed params. |         Tries to create an object using passed params. | ||||||
|         Used by get_or_create and update_or_create |         Used by get_or_create and update_or_create | ||||||
|         """ |         """ | ||||||
|  |         obj = self.model(**params) | ||||||
|  |         sid = transaction.savepoint(using=self.db) | ||||||
|         try: |         try: | ||||||
|             obj = self.model(**params) |  | ||||||
|             sid = transaction.savepoint(using=self.db) |  | ||||||
|             obj.save(force_insert=True, using=self.db) |             obj.save(force_insert=True, using=self.db) | ||||||
|             transaction.savepoint_commit(sid, using=self.db) |             transaction.savepoint_commit(sid, using=self.db) | ||||||
|             return obj, True |             return obj, True | ||||||
|         except DatabaseError: |         except DatabaseError as e: | ||||||
|             transaction.savepoint_rollback(sid, using=self.db) |             transaction.savepoint_rollback(sid, using=self.db) | ||||||
|             exc_info = sys.exc_info() |             if isinstance(e, IntegrityError): | ||||||
|             try: |                 try: | ||||||
|                 return self.get(**lookup), False |                     return self.get(**lookup), False | ||||||
|             except self.model.DoesNotExist: |                 except self.model.DoesNotExist: | ||||||
|                 # Re-raise the DatabaseError with its original traceback. |                     pass | ||||||
|                 six.reraise(*exc_info) |             six.reraise(*sys.exc_info()) | ||||||
|  |  | ||||||
|     def _extract_model_params(self, defaults, **kwargs): |     def _extract_model_params(self, defaults, **kwargs): | ||||||
|         """ |         """ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user