[Django] explore bulk_create, djangobulk_create
When using django orm for mass inserts, we can use bulk_create for batch inserts instead of using the for loop to save one by one. But do we need to add a transaction on our own when using this method? Or does django encapsulate this method as a transaction?
View the source code (django1.5): In django/db/models/query. py, You can see such a snippet.
with transaction.commit_on_success_unless_managed(using=self.db): if (connection.features.can_combine_inserts_with_and_without_auto_increment_pk and self.model._meta.has_auto_field): self._batched_insert(objs, fields, batch_size) else: objs_with_pk, objs_without_pk = partition(lambda o: o.pk is None, objs) if objs_with_pk: self._batched_insert(objs_with_pk, fields, batch_size) if objs_without_pk: fields= [f for f in fields if not isinstance(f, AutoField)] self._batched_insert(objs_without_pk, fields, batch_size)
Here we see a transaction call transaction. commit_on_success_unless_managed (using = self. db). What does this sentence mean? See his definition: django/db/transaction. py.
def commit_on_success_unless_managed(using=None, savepoint=False): """ Transitory API to preserve backwards-compatibility while refactoring. Once the legacy transaction management is fully deprecated, this should simply be replaced by atomic. Until then, it's necessary to guarantee that a commit occurs on exit, which atomic doesn't do when it's nested. Unlike atomic, savepoint defaults to False because that's closer to the legacy behavior. """ connection = get_connection(using) if connection.get_autocommit() or connection.in_atomic_block: return atomic(using, savepoint) else: def entering(using): pass def exiting(exc_type, using): set_dirty(using=using) return _transaction_func(entering, exiting, using)
I didn't quite understand the explanation of this method. From the code structure, there should be transactions. Let's make an experiment and insert two pieces of data into the database in batches. One is correct and the other is wrong. What is the result?
Ipython made a test
From mngm. models import Areaa1 = Area (areaname = "China", code = "CN", parentid = '1', level = '3') a2 = Area (id = 1, areaname = "China", code = "CN", parentid = '1', level = '3') # Area of the error record. objects. bulk_create ([a1, a2]) IntegrityError: (1062, "Duplicate entry '1' for key 'primary'") a2 = Area (areaname = "Chinaa ", code = "CN", parentid = '1', level = '3') # correct record Area. objects. bulk_create ([a1, a2]) [<Area: Area object>, <Area: Area object>]
Therefore, this operation framework has implemented transaction processing, and you do not need to add transactions on your own.
You probably don't need this kind of transaction processing, look at the https://rodmtech.net/docs/django/django-bulk_create-without-integrityerror-rollback/
This article from the "orangleliu notebook" blog, reprint please be sure to keep this source http://blog.csdn.net/orangleliu/article/details/41806263
Author orangleliu adopts signature-non-commercial use-share protocol in the same way