Coverage for src/backend/InvenTree/common/migrations/0026_auto_20240608_1238.py: 32%
43 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 17:47 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 17:47 +0000
1# Generated by Django 4.2.12 on 2024-06-08 12:38
3from django.db import migrations
4from django.core.files.storage import default_storage
7def get_legacy_models():
8 """Return a set of legacy attachment models."""
10 # Legacy attachment types to convert:
11 # app_label, table name, target model, model ref
12 return [
13 ('build', 'BuildOrderAttachment', 'build', 'build'),
14 ('company', 'CompanyAttachment', 'company', 'company'),
15 ('company', 'ManufacturerPartAttachment', 'manufacturerpart', 'manufacturer_part'),
16 ('order', 'PurchaseOrderAttachment', 'purchaseorder', 'order'),
17 ('order', 'SalesOrderAttachment', 'salesorder', 'order'),
18 ('order', 'ReturnOrderAttachment', 'returnorder', 'order'),
19 ('part', 'PartAttachment', 'part', 'part'),
20 ('stock', 'StockItemAttachment', 'stockitem', 'stock_item')
21 ]
24def update_attachments(apps, schema_editor):
25 """Migrate any existing attachment models to the new attachment table."""
27 Attachment = apps.get_model('common', 'attachment')
29 N = 0
31 for app, model, target_model, model_ref in get_legacy_models():
32 LegacyAttachmentModel = apps.get_model(app, model)
34 if LegacyAttachmentModel.objects.count() == 0: 34 ↛ 37line 34 didn't jump to line 37 because the condition on line 34 was always true
35 continue
37 to_create = []
39 for attachment in LegacyAttachmentModel.objects.all():
41 # Find the size of the file (if exists)
42 if attachment.attachment and default_storage.exists(attachment.attachment.name):
43 try:
44 file_size = default_storage.size(attachment.attachment.name)
45 except NotImplementedError:
46 file_size = 0
47 else:
48 file_size = 0
50 to_create.append(
51 Attachment(
52 model_type=target_model,
53 model_id=getattr(attachment, model_ref).pk,
54 attachment=attachment.attachment,
55 link=attachment.link,
56 comment=attachment.comment,
57 upload_date=attachment.upload_date,
58 upload_user=attachment.user,
59 file_size=file_size
60 )
61 )
63 if len(to_create) > 0:
64 print(f"Migrating {len(to_create)} attachments for the legacy '{model}' model.")
65 Attachment.objects.bulk_create(to_create)
67 N += len(to_create)
69 # Check the correct number of Attachment objects has been created
70 assert(N == Attachment.objects.count())
73def reverse_attachments(apps, schema_editor):
74 """Reverse data migration, and map new Attachment model back to legacy models."""
76 Attachment = apps.get_model('common', 'attachment')
78 N = 0
80 for app, model, target_model, model_ref in get_legacy_models():
81 LegacyAttachmentModel = apps.get_model(app, model)
83 to_create = []
85 for attachment in Attachment.objects.filter(model_type=target_model):
87 TargetModel = apps.get_model(app, target_model)
89 data = {
90 'attachment': attachment.attachment,
91 'link': attachment.link,
92 'comment': attachment.comment,
93 'upload_date': attachment.upload_date,
94 'user': attachment.upload_user,
95 model_ref: TargetModel.objects.get(pk=attachment.model_id)
96 }
98 to_create.append(LegacyAttachmentModel(**data))
100 if len(to_create) > 0:
101 print(f"Reversing {len(to_create)} attachments for the legacy '{model}' model.")
102 LegacyAttachmentModel.objects.bulk_create(to_create)
104 N += len(to_create)
106 # Check the correct number of LegacyAttachmentModel objects has been created
107 assert(N == Attachment.objects.count())
109class Migration(migrations.Migration):
111 dependencies = [
112 ('build', '0050_auto_20240508_0138'),
113 ('common', '0025_attachment'),
114 ('company', '0069_company_active'),
115 ('order', '0099_alter_salesorder_status'),
116 ('part', '0123_parttesttemplate_choices'),
117 ('stock', '0110_alter_stockitemtestresult_finished_datetime_and_more')
118 ]
120 operations = [
121 migrations.RunPython(update_attachments, reverse_code=reverse_attachments),
122 ]