Coverage for rest_api/migrations/0073_remove_sample_length_remove_sample_sequence_and_more.py: 38%

42 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-10 03:22 +0000

1# Generated by Django 5.1.7 on 2025-09-19 13:13 

2 

3from django.db import migrations, models 

4from django.utils import timezone 

5 

6 

7def _unique_sequence_name(base_name, used_names, sequence_pk): 

8 base_name = (base_name or f"sequence-{sequence_pk}").strip() 

9 if not base_name: 

10 base_name = f"sequence-{sequence_pk}" 

11 

12 candidate = base_name[:200] 

13 if candidate not in used_names: 

14 used_names.add(candidate) 

15 return candidate 

16 

17 prefix = base_name[:190] or "sequence" 

18 suffix = 1 

19 while True: 

20 candidate = f"{prefix}-{suffix}"[:200] 

21 if candidate not in used_names: 

22 used_names.add(candidate) 

23 return candidate 

24 suffix += 1 

25 

26 

27def backfill_sequence_metadata(apps, schema_editor): 

28 Sample = apps.get_model("rest_api", "Sample") 

29 Sequence = apps.get_model("rest_api", "Sequence") 

30 SampleSequence = Sample.sequences.through 

31 db_alias = schema_editor.connection.alias 

32 

33 used_names = set( 

34 Sequence.objects.using(db_alias) 

35 .exclude(name__isnull=True) 

36 .exclude(name="") 

37 .values_list("name", flat=True) 

38 ) 

39 now = timezone.now() 

40 

41 through_rows = [] 

42 for sequence in Sequence.objects.using(db_alias).all().iterator(): 

43 samples = list( 

44 Sample.objects.using(db_alias).filter(sequence_id=sequence.pk).order_by("id") 

45 ) 

46 

47 preferred_name = next( 

48 (sample.name for sample in samples if sample.name and sample.name.strip()), 

49 None, 

50 ) 

51 sequence.name = _unique_sequence_name( 

52 preferred_name or sequence.seqhash, 

53 used_names, 

54 sequence.pk, 

55 ) 

56 

57 if sequence.length is None: 

58 sequence.length = next( 

59 (sample.length for sample in samples if sample.length is not None), 

60 None, 

61 ) 

62 

63 sequence.init_upload_date = min( 

64 (sample.init_upload_date for sample in samples if sample.init_upload_date), 

65 default=now, 

66 ) 

67 sequence.last_update_date = max( 

68 (sample.last_update_date for sample in samples if sample.last_update_date), 

69 default=None, 

70 ) 

71 sequence.save( 

72 update_fields=[ 

73 "name", 

74 "length", 

75 "init_upload_date", 

76 "last_update_date", 

77 ] 

78 ) 

79 

80 for sample in samples: 

81 through_rows.append( 

82 SampleSequence(sample_id=sample.pk, sequence_id=sequence.pk) 

83 ) 

84 

85 if through_rows: 

86 SampleSequence.objects.using(db_alias).bulk_create(through_rows) 

87 

88 

89class Migration(migrations.Migration): 

90 

91 dependencies = [ 

92 ("rest_api", "0072_remove_aminoacidmutation_is_frameshift_and_more"), 

93 ] 

94 

95 operations = [ 

96 migrations.AddField( 

97 model_name="sample", 

98 name="sequences", 

99 field=models.ManyToManyField( 

100 related_name="samples", to="rest_api.sequence" 

101 ), 

102 ), 

103 migrations.AddField( 

104 model_name="sequence", 

105 name="init_upload_date", 

106 field=models.DateTimeField(blank=True, null=True), 

107 ), 

108 migrations.AddField( 

109 model_name="sequence", 

110 name="last_update_date", 

111 field=models.DateTimeField(blank=True, null=True), 

112 ), 

113 migrations.AddField( 

114 model_name="sequence", 

115 name="length", 

116 field=models.IntegerField(blank=True, null=True), 

117 ), 

118 migrations.AddField( 

119 model_name="sequence", 

120 name="name", 

121 field=models.CharField(blank=True, max_length=200, null=True), 

122 ), 

123 migrations.RunPython(backfill_sequence_metadata, migrations.RunPython.noop), 

124 migrations.RemoveField( 

125 model_name="sample", 

126 name="length", 

127 ), 

128 migrations.RemoveField( 

129 model_name="sample", 

130 name="sequence", 

131 ), 

132 migrations.AlterField( 

133 model_name="sequence", 

134 name="init_upload_date", 

135 field=models.DateTimeField(auto_now=True), 

136 ), 

137 migrations.AlterField( 

138 model_name="sequence", 

139 name="name", 

140 field=models.CharField(max_length=200, unique=True), 

141 ), 

142 migrations.AddIndex( 

143 model_name="sequence", 

144 index=models.Index(fields=["name"], name="sequence_name_455b90_idx"), 

145 ), 

146 migrations.AddIndex( 

147 model_name="sequence", 

148 index=models.Index( 

149 fields=["init_upload_date"], name="sequence_init_up_dd7d45_idx" 

150 ), 

151 ), 

152 migrations.AddIndex( 

153 model_name="sequence", 

154 index=models.Index( 

155 fields=["last_update_date"], name="sequence_last_up_f215ac_idx" 

156 ), 

157 ), 

158 ]