Last active
January 19, 2023 21:02
-
-
Save Flexonze/2d5ac2def78c54186628fe33e27415f9 to your computer and use it in GitHub Desktop.
django-pgbulk vs Django's bulk_create and bulk_update
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from myapp.models import MyModel | |
from django.test import TestCase | |
import pgbulk | |
from time import perf_counter | |
class TestPgBulk(TestCase): | |
@classmethod | |
def setUpTestData(cls): | |
cls.number_of_objects = 25_000 | |
my_models = [] | |
for i in range(cls.number_of_objects): | |
my_models.append( | |
MyModel(name="name") | |
) | |
cls.my_model = MyModel.objects.bulk_create(my_models) | |
def setUp(self): | |
self.assertEqual(MyModel.objects.filter(name="new name").count(), 0) | |
for obj in self.my_model: | |
obj.name = "new name" | |
def test_bulk_update_with_bulk_update(self): | |
with self.assertNumQueries(1): | |
start = perf_counter() | |
MyModel.objects.bulk_update(self.my_model, ["name"]) | |
end = perf_counter() | |
print(f"Time with bulk_update: {end - start} seconds") | |
self.assertEqual(MyModel.objects.filter(name="new name").count(), self.number_of_objects) | |
def test_bulk_update_with_pgbulk(self): | |
with self.assertNumQueries(1): | |
start = perf_counter() | |
pgbulk.update(MyModel, self.my_model, ["name"]) | |
end = perf_counter() | |
print(f"Time with pgbulk.update: {end - start} seconds") | |
self.assertEqual(MyModel.objects.filter(name="new name").count(), self.number_of_objects) | |
def test_upsert_with_pgbulk(self): | |
self.my_model = self.my_model[:self.number_of_objects // 2] | |
self.my_model.extend([MyModel(name="new name") for _ in range(self.number_of_objects // 2)]) | |
with self.assertNumQueries(1): | |
start = perf_counter() | |
results = pgbulk.upsert(MyModel, self.my_model, ["id"], ["name"], returning=True) | |
end = perf_counter() | |
print(f"Time with pgbulk.upsert: {end - start} seconds") | |
print(f"Created: {len([result.id for result in results.created])}") | |
print(f"Updated: {len([result.id for result in results.updated])}") | |
self.assertEqual(MyModel.objects.filter(name="new name").count(), self.number_of_objects) | |
def test_upsert_as_bulk_create(self): | |
my_models = [] | |
for i in range(self.number_of_objects): | |
my_models.append( | |
MyModel(name="new name") | |
) | |
with self.assertNumQueries(1): | |
start = perf_counter() | |
results = pgbulk.upsert(MyModel, my_models, ["id"], ["name"], returning=True) | |
end = perf_counter() | |
print(f"Time with pgbulk.upsert as bulk_create: {end - start} seconds") | |
print(f"Created: {len([result.id for result in results.created])}") | |
print(f"Updated: {len([result.id for result in results.updated])}") | |
self.assertEqual(MyModel.objects.filter(name="new name").count(), self.number_of_objects) | |
def test_upsert_as_bulk_update(self): | |
with self.assertNumQueries(1): | |
start = perf_counter() | |
results = pgbulk.upsert(MyModel, self.my_model, ["id"], ["name"], returning=True) | |
end = perf_counter() | |
print(f"Time with pgbulk.upsert as bulk_update: {end - start} seconds") | |
print(f"Created: {len([result.id for result in results.created])}") | |
print(f"Updated: {len([result.id for result in results.updated])}") | |
self.assertEqual(MyModel.objects.filter(name="new name").count(), self.number_of_objects) | |
def test_django_bulk_create(self): | |
my_models = [] | |
for i in range(self.number_of_objects): | |
my_models.append( | |
MyModel(name="new name") | |
) | |
with self.assertNumQueries(1): | |
start = perf_counter() | |
self.my_model = MyModel.objects.bulk_create(my_models) | |
end = perf_counter() | |
print(f"Time with django_bulk_create: {end - start} seconds") | |
self.assertEqual(MyModel.objects.filter(name="new name").count(), self.number_of_objects) |
Example output:
Time with bulk_update: 21.68879701300102 seconds
Time with pgbulk.update: 0.6510931049997453 seconds
Time with django_bulk_create: 1.6016744959997595 seconds
Time with pgbulk.upsert as bulk_create: 1.7720716830008314 seconds
Created: 25000
Updated: 0
Time with pgbulk.upsert as bulk_update: 2.0506603350004298 seconds
Created: 0
Updated: 25000
Time with pgbulk.upsert: 1.9862078459991608 seconds
Created: 12500
Updated: 12500
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Refs:
https://github.com/Opus10/django-pgbulk
https://docs.djangoproject.com/en/dev/ref/models/querysets/#bulk-create
https://docs.djangoproject.com/en/dev/ref/models/querysets/#bulk-update