mirror of
https://github.com/inventree/InvenTree.git
synced 2026-05-06 09:43:38 +00:00
[refactor] bulk operation batch size (#11864)
* Fetch models properly during migration * Specify batch_size when performing bulk_update operations * Enforce batch_size for bulk_create operations * Fix typo * Revert typo fix - Changes API schema
This commit is contained in:
@@ -594,7 +594,7 @@ class InvenTreeParameterMixin(InvenTreePermissionCheckMixin, models.Model):
|
|||||||
parameters.append(parameter)
|
parameters.append(parameter)
|
||||||
|
|
||||||
if len(parameters) > 0:
|
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):
|
def get_parameter(self, name: str):
|
||||||
"""Return a Parameter instance for the given parameter name.
|
"""Return a Parameter instance for the given parameter name.
|
||||||
|
|||||||
@@ -975,10 +975,10 @@ class Build(
|
|||||||
allocations.extend(new_allocations)
|
allocations.extend(new_allocations)
|
||||||
|
|
||||||
# Bulk create tracking entries
|
# Bulk create tracking entries
|
||||||
stock.models.StockItemTracking.objects.bulk_create(tracking)
|
stock.models.StockItemTracking.objects.bulk_create(tracking, batch_size=250)
|
||||||
|
|
||||||
# Generate stock allocations
|
# Generate stock allocations
|
||||||
BuildItem.objects.bulk_create(allocations)
|
BuildItem.objects.bulk_create(allocations, batch_size=250)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
"""Create a single build output of the given quantity."""
|
"""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))
|
new_items.extend(self.auto_allocate_tracked_output(output, **kwargs))
|
||||||
|
|
||||||
# Bulk-create the new BuildItem objects
|
# 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):
|
def auto_allocate_untracked_stock(self, **kwargs):
|
||||||
"""Automatically allocate untracked stock items against this build order.
|
"""Automatically allocate untracked stock items against this build order.
|
||||||
@@ -1530,7 +1530,7 @@ class Build(
|
|||||||
break
|
break
|
||||||
|
|
||||||
# Bulk-create the new BuildItem objects
|
# 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:
|
def unallocated_lines(self, tracked: Optional[bool] = None) -> QuerySet:
|
||||||
"""Returns a list of BuildLine objects which have not been fully allocated."""
|
"""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))
|
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:
|
if len(lines) > 0:
|
||||||
logger.info('Created %s BuildLine objects for BuildOrder', len(lines))
|
logger.info('Created %s BuildLine objects for BuildOrder', len(lines))
|
||||||
|
|||||||
@@ -247,11 +247,14 @@ class BaseInvenTreeSetting(models.Model):
|
|||||||
|
|
||||||
if len(missing_keys) > 0:
|
if len(missing_keys) > 0:
|
||||||
logger.info('Building %s default values for %s', len(missing_keys), cls)
|
logger.info('Building %s default values for %s', len(missing_keys), cls)
|
||||||
cls.objects.bulk_create([
|
cls.objects.bulk_create(
|
||||||
|
[
|
||||||
cls(key=key, value=cls.get_setting_default(key), **kwargs)
|
cls(key=key, value=cls.get_setting_default(key), **kwargs)
|
||||||
for key in missing_keys
|
for key in missing_keys
|
||||||
if not key.startswith('_')
|
if not key.startswith('_')
|
||||||
])
|
],
|
||||||
|
batch_size=250,
|
||||||
|
)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.exception(
|
logger.exception(
|
||||||
'Failed to build default values for %s (%s)', cls, type(exc)
|
'Failed to build default values for %s (%s)', cls, type(exc)
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ class DataImportSession(models.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Create the column mappings
|
# 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.status = DataImportStatusCode.MAPPING.value
|
||||||
self.save()
|
self.save()
|
||||||
@@ -337,7 +337,7 @@ class DataImportSession(models.Model):
|
|||||||
imported_rows.append(row)
|
imported_rows.append(row)
|
||||||
|
|
||||||
# Perform database writes as a single operation
|
# 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"
|
# Mark the import task as "PROCESSING"
|
||||||
self.status = DataImportStatusCode.PROCESSING.value
|
self.status = DataImportStatusCode.PROCESSING.value
|
||||||
|
|||||||
@@ -1173,7 +1173,9 @@ class PurchaseOrder(TotalPriceMixin, Order):
|
|||||||
|
|
||||||
# Bulk create new stock items
|
# Bulk create new stock items
|
||||||
if len(bulk_create_items) > 0:
|
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
|
# Fetch them back again
|
||||||
tree_ids = [item.tree_id for item in bulk_create_items]
|
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
|
# 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
|
# Update received quantity for each line item
|
||||||
PurchaseOrderLineItem.objects.bulk_update(line_items_to_update, ['received'])
|
PurchaseOrderLineItem.objects.bulk_update(line_items_to_update, ['received'])
|
||||||
|
|||||||
@@ -1901,7 +1901,9 @@ class SalesOrderSerialAllocationSerializer(serializers.Serializer):
|
|||||||
)
|
)
|
||||||
|
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
order.models.SalesOrderAllocation.objects.bulk_create(allocations)
|
order.models.SalesOrderAllocation.objects.bulk_create(
|
||||||
|
allocations, batch_size=250
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class SalesOrderShipmentAllocationSerializer(serializers.Serializer):
|
class SalesOrderShipmentAllocationSerializer(serializers.Serializer):
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ def update_category_parameters(apps, schema_editor):
|
|||||||
PartCategoryParameterTemplate.objects.bulk_update(
|
PartCategoryParameterTemplate.objects.bulk_update(
|
||||||
category_parameters_to_update,
|
category_parameters_to_update,
|
||||||
fields=["template"],
|
fields=["template"],
|
||||||
|
batch_size=250,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -47,6 +48,7 @@ def reverse_update_category_parameters(apps, schema_editor):
|
|||||||
PartCategoryParameterTemplate.objects.bulk_update(
|
PartCategoryParameterTemplate.objects.bulk_update(
|
||||||
category_parameters_to_update,
|
category_parameters_to_update,
|
||||||
fields=["parameter_template"],
|
fields=["parameter_template"],
|
||||||
|
batch_size=250,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,9 +10,10 @@ def update_bom_role(apps, schema_editor):
|
|||||||
we need to update the ruleset to include the correct models.
|
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.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 each existing group, create a new 'bom' ruleset
|
||||||
for group in Group.objects.all():
|
for group in Group.objects.all():
|
||||||
|
|||||||
@@ -2462,7 +2462,7 @@ class Part(
|
|||||||
templates.append(template)
|
templates.append(template)
|
||||||
|
|
||||||
if len(templates) > 0:
|
if len(templates) > 0:
|
||||||
PartTestTemplate.objects.bulk_create(templates)
|
PartTestTemplate.objects.bulk_create(templates, batch_size=250)
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def copy_category_parameters(self, category: PartCategory):
|
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(
|
def getTestTemplates(
|
||||||
self, required=None, include_parent: bool = True, enabled=None
|
self, required=None, include_parent: bool = True, enabled=None
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ def perform_stocktake(
|
|||||||
|
|
||||||
if generate_entry:
|
if generate_entry:
|
||||||
# Bulk-create PartStocktake entries
|
# 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:
|
if report_output:
|
||||||
# Save report data, and mark as complete
|
# Save report data, and mark as complete
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class InvenTreeUINotifications(NotificationMixin, InvenTreePlugin):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
NotificationMessage.objects.bulk_create(entries)
|
NotificationMessage.objects.bulk_create(entries, batch_size=250)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
@@ -1234,7 +1234,7 @@ class StockList(
|
|||||||
):
|
):
|
||||||
tracking.append(entry)
|
tracking.append(entry)
|
||||||
|
|
||||||
StockItemTracking.objects.bulk_create(tracking)
|
StockItemTracking.objects.bulk_create(tracking, batch_size=250)
|
||||||
|
|
||||||
# Annotate the stock items with part information
|
# Annotate the stock items with part information
|
||||||
queryset = StockSerializers.StockItemSerializer.annotate_queryset(items)
|
queryset = StockSerializers.StockItemSerializer.annotate_queryset(items)
|
||||||
|
|||||||
@@ -634,7 +634,7 @@ class StockItem(
|
|||||||
items.append(StockItem(**data))
|
items.append(StockItem(**data))
|
||||||
|
|
||||||
# Create the StockItem objects in bulk
|
# 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
|
# We will need to rebuild the stock item tree manually, due to the bulk_create operation
|
||||||
if parent and parent.tree_id:
|
if parent and parent.tree_id:
|
||||||
@@ -1973,7 +1973,7 @@ class StockItem(
|
|||||||
# Copy any test results from this item to the new one
|
# Copy any test results from this item to the new one
|
||||||
item.copyTestResultsFrom(self)
|
item.copyTestResultsFrom(self)
|
||||||
|
|
||||||
StockItemTracking.objects.bulk_create(history_items)
|
StockItemTracking.objects.bulk_create(history_items, batch_size=250)
|
||||||
|
|
||||||
# Remove the equivalent number of items
|
# Remove the equivalent number of items
|
||||||
self.take_stock(
|
self.take_stock(
|
||||||
@@ -2008,7 +2008,7 @@ class StockItem(
|
|||||||
result.stock_item = self
|
result.stock_item = self
|
||||||
results_to_create.append(result)
|
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):
|
def add_test_result(self, create_template=True, **kwargs):
|
||||||
"""Helper function to add a new StockItemTestResult.
|
"""Helper function to add a new StockItemTestResult.
|
||||||
|
|||||||
@@ -1128,7 +1128,7 @@ class StockChangeStatusSerializer(serializers.Serializer):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Create tracking entries
|
# Create tracking entries
|
||||||
StockItemTracking.objects.bulk_create(transaction_notes)
|
StockItemTracking.objects.bulk_create(transaction_notes, batch_size=250)
|
||||||
|
|
||||||
|
|
||||||
class StockLocationTypeSerializer(InvenTree.serializers.InvenTreeModelSerializer):
|
class StockLocationTypeSerializer(InvenTree.serializers.InvenTreeModelSerializer):
|
||||||
|
|||||||
@@ -602,9 +602,7 @@ class StockItemListTest(StockAPITestCase):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if len(items) >= 100:
|
StockItem.objects.bulk_create(items, batch_size=250)
|
||||||
StockItem.objects.bulk_create(items)
|
|
||||||
items = []
|
|
||||||
|
|
||||||
self.assertEqual(StockItem.objects.count(), 1000)
|
self.assertEqual(StockItem.objects.count(), 1000)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user