diff --git a/src/backend/InvenTree/InvenTree/models.py b/src/backend/InvenTree/InvenTree/models.py index f0bb8dc11d..b876c7c8d2 100644 --- a/src/backend/InvenTree/InvenTree/models.py +++ b/src/backend/InvenTree/InvenTree/models.py @@ -594,7 +594,7 @@ class InvenTreeParameterMixin(InvenTreePermissionCheckMixin, models.Model): parameters.append(parameter) if len(parameters) > 0: - common.models.Parameter.objects.bulk_create(parameters) + common.models.Parameter.objects.bulk_create(parameters, batch_size=250) def get_parameter(self, name: str): """Return a Parameter instance for the given parameter name. diff --git a/src/backend/InvenTree/build/models.py b/src/backend/InvenTree/build/models.py index c908bddd24..24b3914209 100644 --- a/src/backend/InvenTree/build/models.py +++ b/src/backend/InvenTree/build/models.py @@ -975,10 +975,10 @@ class Build( allocations.extend(new_allocations) # Bulk create tracking entries - stock.models.StockItemTracking.objects.bulk_create(tracking) + stock.models.StockItemTracking.objects.bulk_create(tracking, batch_size=250) # Generate stock allocations - BuildItem.objects.bulk_create(allocations) + BuildItem.objects.bulk_create(allocations, batch_size=250) else: """Create a single build output of the given quantity.""" @@ -1389,7 +1389,7 @@ class Build( new_items.extend(self.auto_allocate_tracked_output(output, **kwargs)) # Bulk-create the new BuildItem objects - BuildItem.objects.bulk_create(new_items) + BuildItem.objects.bulk_create(new_items, batch_size=250) def auto_allocate_untracked_stock(self, **kwargs): """Automatically allocate untracked stock items against this build order. @@ -1530,7 +1530,7 @@ class Build( break # Bulk-create the new BuildItem objects - BuildItem.objects.bulk_create(new_items) + BuildItem.objects.bulk_create(new_items, batch_size=250) def unallocated_lines(self, tracked: Optional[bool] = None) -> QuerySet: """Returns a list of BuildLine objects which have not been fully allocated.""" @@ -1655,7 +1655,7 @@ class Build( lines.append(BuildLine(build=self, bom_item=bom_item, quantity=quantity)) - BuildLine.objects.bulk_create(lines) + BuildLine.objects.bulk_create(lines, batch_size=250) if len(lines) > 0: logger.info('Created %s BuildLine objects for BuildOrder', len(lines)) diff --git a/src/backend/InvenTree/common/models.py b/src/backend/InvenTree/common/models.py index 2cb7e33104..f66a15d14f 100644 --- a/src/backend/InvenTree/common/models.py +++ b/src/backend/InvenTree/common/models.py @@ -247,11 +247,14 @@ class BaseInvenTreeSetting(models.Model): if len(missing_keys) > 0: logger.info('Building %s default values for %s', len(missing_keys), cls) - cls.objects.bulk_create([ - cls(key=key, value=cls.get_setting_default(key), **kwargs) - for key in missing_keys - if not key.startswith('_') - ]) + cls.objects.bulk_create( + [ + cls(key=key, value=cls.get_setting_default(key), **kwargs) + for key in missing_keys + if not key.startswith('_') + ], + batch_size=250, + ) except Exception as exc: logger.exception( 'Failed to build default values for %s (%s)', cls, type(exc) diff --git a/src/backend/InvenTree/importer/models.py b/src/backend/InvenTree/importer/models.py index d1c714bffa..8dae1376ab 100644 --- a/src/backend/InvenTree/importer/models.py +++ b/src/backend/InvenTree/importer/models.py @@ -241,7 +241,7 @@ class DataImportSession(models.Model): ) # Create the column mappings - DataImportColumnMap.objects.bulk_create(column_mappings) + DataImportColumnMap.objects.bulk_create(column_mappings, batch_size=250) self.status = DataImportStatusCode.MAPPING.value self.save() @@ -337,7 +337,7 @@ class DataImportSession(models.Model): imported_rows.append(row) # Perform database writes as a single operation - DataImportRow.objects.bulk_create(imported_rows) + DataImportRow.objects.bulk_create(imported_rows, batch_size=250) # Mark the import task as "PROCESSING" self.status = DataImportStatusCode.PROCESSING.value diff --git a/src/backend/InvenTree/order/models.py b/src/backend/InvenTree/order/models.py index 58a67ef1f3..2e36b6228c 100644 --- a/src/backend/InvenTree/order/models.py +++ b/src/backend/InvenTree/order/models.py @@ -1173,7 +1173,9 @@ class PurchaseOrder(TotalPriceMixin, Order): # Bulk create new stock items if len(bulk_create_items) > 0: - stock.models.StockItem.objects.bulk_create(bulk_create_items) + stock.models.StockItem.objects.bulk_create( + bulk_create_items, batch_size=250 + ) # Fetch them back again tree_ids = [item.tree_id for item in bulk_create_items] @@ -1200,7 +1202,9 @@ class PurchaseOrder(TotalPriceMixin, Order): ) # Bulk create new tracking entries for each item - stock.models.StockItemTracking.objects.bulk_create(tracking_entries) + stock.models.StockItemTracking.objects.bulk_create( + tracking_entries, batch_size=250 + ) # Update received quantity for each line item PurchaseOrderLineItem.objects.bulk_update(line_items_to_update, ['received']) diff --git a/src/backend/InvenTree/order/serializers.py b/src/backend/InvenTree/order/serializers.py index e1a8de16f6..c544d3b76d 100644 --- a/src/backend/InvenTree/order/serializers.py +++ b/src/backend/InvenTree/order/serializers.py @@ -1901,7 +1901,9 @@ class SalesOrderSerialAllocationSerializer(serializers.Serializer): ) with transaction.atomic(): - order.models.SalesOrderAllocation.objects.bulk_create(allocations) + order.models.SalesOrderAllocation.objects.bulk_create( + allocations, batch_size=250 + ) class SalesOrderShipmentAllocationSerializer(serializers.Serializer): diff --git a/src/backend/InvenTree/part/migrations/0145_auto_20251203_1238.py b/src/backend/InvenTree/part/migrations/0145_auto_20251203_1238.py index 0924f9065e..1a8ddea9a8 100644 --- a/src/backend/InvenTree/part/migrations/0145_auto_20251203_1238.py +++ b/src/backend/InvenTree/part/migrations/0145_auto_20251203_1238.py @@ -24,6 +24,7 @@ def update_category_parameters(apps, schema_editor): PartCategoryParameterTemplate.objects.bulk_update( category_parameters_to_update, fields=["template"], + batch_size=250, ) @@ -47,6 +48,7 @@ def reverse_update_category_parameters(apps, schema_editor): PartCategoryParameterTemplate.objects.bulk_update( category_parameters_to_update, fields=["parameter_template"], + batch_size=250, ) diff --git a/src/backend/InvenTree/part/migrations/0148_auto_20260427_2233.py b/src/backend/InvenTree/part/migrations/0148_auto_20260427_2233.py index 2b6d8d8e7c..995e064556 100644 --- a/src/backend/InvenTree/part/migrations/0148_auto_20260427_2233.py +++ b/src/backend/InvenTree/part/migrations/0148_auto_20260427_2233.py @@ -10,9 +10,10 @@ def update_bom_role(apps, schema_editor): we need to update the ruleset to include the correct models. """ - from django.contrib.auth.models import Group from users.ruleset import RuleSetEnum - from users.models import RuleSet + + Group = apps.get_model("auth", "Group") + RuleSet = apps.get_model("users", "RuleSet") # For each existing group, create a new 'bom' ruleset for group in Group.objects.all(): diff --git a/src/backend/InvenTree/part/models.py b/src/backend/InvenTree/part/models.py index c006312851..f9e94d4649 100644 --- a/src/backend/InvenTree/part/models.py +++ b/src/backend/InvenTree/part/models.py @@ -2462,7 +2462,7 @@ class Part( templates.append(template) if len(templates) > 0: - PartTestTemplate.objects.bulk_create(templates) + PartTestTemplate.objects.bulk_create(templates, batch_size=250) @transaction.atomic def copy_category_parameters(self, category: PartCategory): @@ -2504,7 +2504,7 @@ class Part( ) ) - Parameter.objects.bulk_create(parameters) + Parameter.objects.bulk_create(parameters, batch_size=250) def getTestTemplates( self, required=None, include_parent: bool = True, enabled=None diff --git a/src/backend/InvenTree/part/stocktake.py b/src/backend/InvenTree/part/stocktake.py index 40bc857afd..a7b971680a 100644 --- a/src/backend/InvenTree/part/stocktake.py +++ b/src/backend/InvenTree/part/stocktake.py @@ -208,7 +208,7 @@ def perform_stocktake( if generate_entry: # Bulk-create PartStocktake entries - part_models.PartStocktake.objects.bulk_create(history_entries) + part_models.PartStocktake.objects.bulk_create(history_entries, batch_size=250) if report_output: # Save report data, and mark as complete diff --git a/src/backend/InvenTree/plugin/builtin/integration/core_notifications.py b/src/backend/InvenTree/plugin/builtin/integration/core_notifications.py index a35df5739d..2f7d7b11ca 100644 --- a/src/backend/InvenTree/plugin/builtin/integration/core_notifications.py +++ b/src/backend/InvenTree/plugin/builtin/integration/core_notifications.py @@ -55,7 +55,7 @@ class InvenTreeUINotifications(NotificationMixin, InvenTreePlugin): ) ) - NotificationMessage.objects.bulk_create(entries) + NotificationMessage.objects.bulk_create(entries, batch_size=250) return True diff --git a/src/backend/InvenTree/stock/api.py b/src/backend/InvenTree/stock/api.py index c26091a3d7..1dd10a5c55 100644 --- a/src/backend/InvenTree/stock/api.py +++ b/src/backend/InvenTree/stock/api.py @@ -1234,7 +1234,7 @@ class StockList( ): tracking.append(entry) - StockItemTracking.objects.bulk_create(tracking) + StockItemTracking.objects.bulk_create(tracking, batch_size=250) # Annotate the stock items with part information queryset = StockSerializers.StockItemSerializer.annotate_queryset(items) diff --git a/src/backend/InvenTree/stock/models.py b/src/backend/InvenTree/stock/models.py index d941919706..d2daf164c6 100644 --- a/src/backend/InvenTree/stock/models.py +++ b/src/backend/InvenTree/stock/models.py @@ -634,7 +634,7 @@ class StockItem( items.append(StockItem(**data)) # Create the StockItem objects in bulk - StockItem.objects.bulk_create(items) + StockItem.objects.bulk_create(items, batch_size=250) # We will need to rebuild the stock item tree manually, due to the bulk_create operation if parent and parent.tree_id: @@ -1973,7 +1973,7 @@ class StockItem( # Copy any test results from this item to the new one item.copyTestResultsFrom(self) - StockItemTracking.objects.bulk_create(history_items) + StockItemTracking.objects.bulk_create(history_items, batch_size=250) # Remove the equivalent number of items self.take_stock( @@ -2008,7 +2008,7 @@ class StockItem( result.stock_item = self results_to_create.append(result) - StockItemTestResult.objects.bulk_create(results_to_create) + StockItemTestResult.objects.bulk_create(results_to_create, batch_size=250) def add_test_result(self, create_template=True, **kwargs): """Helper function to add a new StockItemTestResult. diff --git a/src/backend/InvenTree/stock/serializers.py b/src/backend/InvenTree/stock/serializers.py index 35a5885430..c1d6b5e94f 100644 --- a/src/backend/InvenTree/stock/serializers.py +++ b/src/backend/InvenTree/stock/serializers.py @@ -1128,7 +1128,7 @@ class StockChangeStatusSerializer(serializers.Serializer): ) # Create tracking entries - StockItemTracking.objects.bulk_create(transaction_notes) + StockItemTracking.objects.bulk_create(transaction_notes, batch_size=250) class StockLocationTypeSerializer(InvenTree.serializers.InvenTreeModelSerializer): diff --git a/src/backend/InvenTree/stock/test_api.py b/src/backend/InvenTree/stock/test_api.py index e2a7b22b0c..e5b3bfe782 100644 --- a/src/backend/InvenTree/stock/test_api.py +++ b/src/backend/InvenTree/stock/test_api.py @@ -602,9 +602,7 @@ class StockItemListTest(StockAPITestCase): ) ) - if len(items) >= 100: - StockItem.objects.bulk_create(items) - items = [] + StockItem.objects.bulk_create(items, batch_size=250) self.assertEqual(StockItem.objects.count(), 1000)