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

1# Generated by Django 4.2.12 on 2024-06-08 12:38 

2 

3from django.db import migrations 

4from django.core.files.storage import default_storage 

5 

6 

7def get_legacy_models(): 

8 """Return a set of legacy attachment models.""" 

9 

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 ] 

22 

23 

24def update_attachments(apps, schema_editor): 

25 """Migrate any existing attachment models to the new attachment table.""" 

26 

27 Attachment = apps.get_model('common', 'attachment') 

28 

29 N = 0 

30 

31 for app, model, target_model, model_ref in get_legacy_models(): 

32 LegacyAttachmentModel = apps.get_model(app, model) 

33 

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 

36 

37 to_create = [] 

38 

39 for attachment in LegacyAttachmentModel.objects.all(): 

40 

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 

49 

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 ) 

62 

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) 

66 

67 N += len(to_create) 

68 

69 # Check the correct number of Attachment objects has been created 

70 assert(N == Attachment.objects.count()) 

71 

72 

73def reverse_attachments(apps, schema_editor): 

74 """Reverse data migration, and map new Attachment model back to legacy models.""" 

75 

76 Attachment = apps.get_model('common', 'attachment') 

77 

78 N = 0 

79 

80 for app, model, target_model, model_ref in get_legacy_models(): 

81 LegacyAttachmentModel = apps.get_model(app, model) 

82 

83 to_create = [] 

84 

85 for attachment in Attachment.objects.filter(model_type=target_model): 

86 

87 TargetModel = apps.get_model(app, target_model) 

88 

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 } 

97 

98 to_create.append(LegacyAttachmentModel(**data)) 

99 

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) 

103 

104 N += len(to_create) 

105 

106 # Check the correct number of LegacyAttachmentModel objects has been created 

107 assert(N == Attachment.objects.count()) 

108 

109class Migration(migrations.Migration): 

110 

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 ] 

119 

120 operations = [ 

121 migrations.RunPython(update_attachments, reverse_code=reverse_attachments), 

122 ]