|
1 | 1 | from django.db import transaction
|
| 2 | +from django.forms.models import model_to_dict |
2 | 3 |
|
3 | 4 | from simple_history.exceptions import NotHistoricalModelError
|
4 | 5 |
|
@@ -40,16 +41,30 @@ def bulk_create_with_history(objs, model, batch_size=None):
|
40 | 41 | """
|
41 | 42 | Bulk create the objects specified by objs while also bulk creating
|
42 | 43 | their history (all in one transaction).
|
| 44 | + Because of not providing primary key attribute after bulk_create on any DB except |
| 45 | + Postgres (https://docs.djangoproject.com/en/2.2/ref/models/querysets/#bulk-create) |
| 46 | + Divide this process on two transactions for other DB's |
43 | 47 | :param objs: List of objs (not yet saved to the db) of type model
|
44 | 48 | :param model: Model class that should be created
|
45 | 49 | :param batch_size: Number of objects that should be created in each batch
|
46 | 50 | :return: List of objs with IDs
|
47 | 51 | """
|
48 | 52 |
|
49 | 53 | history_manager = get_history_manager_for_model(model)
|
50 |
| - |
| 54 | + second_transaction_required = True |
51 | 55 | with transaction.atomic(savepoint=False):
|
52 | 56 | objs_with_id = model.objects.bulk_create(objs, batch_size=batch_size)
|
53 |
| - history_manager.bulk_history_create(objs_with_id, batch_size=batch_size) |
54 |
| - |
| 57 | + if objs_with_id and objs_with_id[0].pk: |
| 58 | + second_transaction_required = False |
| 59 | + history_manager.bulk_history_create(objs_with_id, batch_size=batch_size) |
| 60 | + if second_transaction_required: |
| 61 | + obj_list = [] |
| 62 | + with transaction.atomic(savepoint=False): |
| 63 | + for obj in objs_with_id: |
| 64 | + attributes = dict( |
| 65 | + filter(lambda x: x[1] is not None, model_to_dict(obj).items()) |
| 66 | + ) |
| 67 | + obj_list += model.objects.filter(**attributes) |
| 68 | + history_manager.bulk_history_create(obj_list, batch_size=batch_size) |
| 69 | + objs_with_id = obj_list |
55 | 70 | return objs_with_id
|
0 commit comments