Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix ulid namespace and migrations issues #1891

Merged
merged 1 commit into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ requests = "==2.31.0"
sentry-sdk = "==1.30.0"
whitenoise = "==6.5.0"
redis-om = "==0.2.1"
django-ulid = "==0.0.4"

[dev-packages]
black = "==23.9.1"
Expand Down
32 changes: 12 additions & 20 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion care/facility/api/serializers/events.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django_ulid.serializers import ULIDField
from rest_framework.serializers import ModelSerializer, SerializerMethodField

from care.facility.models.events import EventType, PatientConsultationEvent
from care.utils.ulid.serializers import ULIDField


class EventTypeSerializer(ModelSerializer):
Expand All @@ -18,7 +18,7 @@
fields = ("id", "parent", "name", "description", "model", "fields", "children")

def get_children(self, obj: EventType) -> list[EventType] | None:
return NestedEventTypeSerializer(obj.children.all(), many=True).data or None

Check warning on line 21 in care/facility/api/serializers/events.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/events.py#L21

Added line #L21 was not covered by tests


class PatientConsultationEventDetailSerializer(ModelSerializer):
Expand Down
2 changes: 1 addition & 1 deletion care/facility/migrations/0408_patientnotesedit.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def create_initial_patient_notes_edit_record(apps, schema_editor):
PatientNotes = apps.get_model("facility", "PatientNotes")
PatientNotesEdit = apps.get_model("facility", "PatientNotesEdit")

notes_without_edits = PatientNotes.objects.all()
notes_without_edits = PatientNotes.objects.all().order_by("pk")

paginator = Paginator(notes_without_edits, 1000)
for page_number in paginator.page_range:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def forwards_func(apps, schema_editor):

asset_content_type = ContentType.objects.get_for_model(Asset)

aar_records = AssetAvailabilityRecord.objects.all()
aar_records = AssetAvailabilityRecord.objects.all().order_by("pk")

paginator = Paginator(aar_records, 1000)
for page_number in paginator.page_range:
Expand All @@ -41,7 +41,9 @@ def backwards_func(apps, schema_editor):

asset_content_type = ContentType.objects.get_for_model(Asset)

ar_records = AvailabilityRecord.objects.filter(content_type=asset_content_type)
ar_records = AvailabilityRecord.objects.filter(
content_type=asset_content_type
).order_by("pk")

paginator = Paginator(ar_records, 1000)
for page_number in paginator.page_range:
Expand Down Expand Up @@ -121,7 +123,6 @@ class Migration(migrations.Migration):
],
options={
"ordering": ["-timestamp"],
"unique_together": {("object_external_id", "timestamp")},
},
),
migrations.AddIndex(
Expand All @@ -131,10 +132,6 @@ class Migration(migrations.Migration):
name="facility_av_content_ad9eff_idx",
),
),
migrations.AlterUniqueTogether(
name="availabilityrecord",
unique_together={("object_external_id", "timestamp")},
),
migrations.RunPython(forwards_func, backwards_func),
migrations.DeleteModel(
name="AssetAvailabilityRecord",
Expand Down
12 changes: 12 additions & 0 deletions care/facility/migrations/0411_merge_20240212_1429.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Generated by Django 4.2.10 on 2024-02-12 08:59

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("facility", "0408_patientnotesedit"),
("facility", "0410_availabilityrecord_delete_assetavailabilityrecord_and_more"),
]

operations = []
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from django.db import migrations, models


def clean_duplicates(apps, schema_editor):
AvailabilityRecord = apps.get_model("facility", "AvailabilityRecord")

duplicates = (
AvailabilityRecord.objects.values("object_external_id", "timestamp")
.annotate(count=models.Count("id"))
.filter(count__gt=1)
)

ids_to_delete = []
for duplicate in duplicates:
record_ids = list(
AvailabilityRecord.objects.filter(
object_external_id=duplicate["object_external_id"],
timestamp=duplicate["timestamp"],
).values_list("id", flat=True)
)

ids_to_delete.extend(record_ids[1:])

if ids_to_delete:
AvailabilityRecord.objects.filter(id__in=set(ids_to_delete)).delete()


class Migration(migrations.Migration):
dependencies = [
("facility", "0411_merge_20240212_1429"),
]

operations = [
migrations.RunPython(clean_duplicates, reverse_code=migrations.RunPython.noop),
migrations.AddConstraint(
model_name="availabilityrecord",
constraint=models.UniqueConstraint(
fields=("object_external_id", "timestamp"),
name="object_external_id_timestamp_unique",
),
),
]
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
# Generated by Django 4.2.8 on 2024-02-10 14:40
# Generated by Django 4.2.10 on 2024-02-12 10:31

import django.contrib.postgres.fields
import django.db.models.deletion
import django_ulid.models
import ulid.api.api
from django.conf import settings
from django.db import migrations, models

import care.utils.event_utils
import care.utils.ulid.models
import care.utils.ulid.ulid


class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
("facility", "0409_merge_20240210_1510"),
("facility", "0412_availabilityrecord_unique_constraint"),
]

operations = [
Expand Down Expand Up @@ -42,15 +42,6 @@ class Migration(migrations.Migration):
),
("created_date", models.DateTimeField(auto_now_add=True)),
("is_active", models.BooleanField(default=True)),
(
"parent",
models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.PROTECT,
related_name="children",
to="facility.eventtype",
),
),
],
),
migrations.CreateModel(
Expand All @@ -67,8 +58,8 @@ class Migration(migrations.Migration):
),
(
"external_id",
django_ulid.models.ULIDField(
default=ulid.api.api.Api.new, editable=False, unique=True
care.utils.ulid.models.ULIDField(
default=care.utils.ulid.ulid.ULID, editable=False, unique=True
),
),
("created_date", models.DateTimeField(db_index=True)),
Expand Down Expand Up @@ -99,37 +90,60 @@ class Migration(migrations.Migration):
max_length=10,
),
),
(
"caused_by",
models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT,
to=settings.AUTH_USER_MODEL,
),
),
(
"consultation",
models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT,
related_name="events",
to="facility.patientconsultation",
),
),
(
"event_type",
models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT,
to="facility.eventtype",
),
),
],
options={
"ordering": ["-created_date"],
"indexes": [
models.Index(
fields=["consultation", "is_latest"],
name="facility_pa_consult_7b22fe_idx",
)
],
},
),
migrations.RemoveConstraint(
model_name="availabilityrecord",
name="object_external_id_timestamp_unique",
),
migrations.AddConstraint(
model_name="availabilityrecord",
constraint=models.UniqueConstraint(
fields=("object_external_id", "timestamp"),
name="object_external_id_timestamp",
),
),
migrations.AddField(
model_name="patientconsultationevent",
name="caused_by",
field=models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL
),
),
migrations.AddField(
model_name="patientconsultationevent",
name="consultation",
field=models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT,
related_name="events",
to="facility.patientconsultation",
),
),
migrations.AddField(
model_name="patientconsultationevent",
name="event_type",
field=models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT, to="facility.eventtype"
),
),
migrations.AddField(
model_name="eventtype",
name="parent",
field=models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.PROTECT,
related_name="children",
to="facility.eventtype",
),
),
migrations.AddIndex(
model_name="patientconsultationevent",
index=models.Index(
fields=["consultation", "is_latest"],
name="facility_pa_consult_7b22fe_idx",
),
),
]
7 changes: 6 additions & 1 deletion care/facility/models/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,16 +209,21 @@
indexes = [
models.Index(fields=["content_type", "object_external_id"]),
]
unique_together = (("object_external_id", "timestamp"),)
constraints = [
models.UniqueConstraint(
name="object_external_id_timestamp",
fields=["object_external_id", "timestamp"],
)
]
ordering = ["-timestamp"]

def __str__(self):
return f"{self.content_type} ({self.object_external_id}) - {self.status} - {self.timestamp}"

Check warning on line 221 in care/facility/models/asset.py

View check run for this annotation

Codecov / codecov/patch

care/facility/models/asset.py#L221

Added line #L221 was not covered by tests

@property
def content_object(self):
model = self.content_type.model_class()
return model.objects.get(external_id=self.object_external_id)

Check warning on line 226 in care/facility/models/asset.py

View check run for this annotation

Codecov / codecov/patch

care/facility/models/asset.py#L225-L226

Added lines #L225 - L226 were not covered by tests


class UserDefaultAssetLocation(BaseModel):
Expand Down
5 changes: 3 additions & 2 deletions care/facility/models/events.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from django.contrib.auth import get_user_model
from django.contrib.postgres.fields import ArrayField
from django.db import models
from django_ulid.models import ULIDField, default

from care.utils.event_utils import CustomJSONEncoder
from care.utils.ulid.models import ULIDField
from care.utils.ulid.ulid import ULID

User = get_user_model()

Expand Down Expand Up @@ -31,22 +32,22 @@
is_active = models.BooleanField(default=True)

def get_descendants(self):
descendants = list(self.children.all())

Check warning on line 35 in care/facility/models/events.py

View check run for this annotation

Codecov / codecov/patch

care/facility/models/events.py#L35

Added line #L35 was not covered by tests
for child in self.children.all():
descendants.extend(child.get_descendants())
return descendants

Check warning on line 38 in care/facility/models/events.py

View check run for this annotation

Codecov / codecov/patch

care/facility/models/events.py#L37-L38

Added lines #L37 - L38 were not covered by tests

def save(self, *args, **kwargs):
if self.description is not None and not self.description.strip():
self.description = None
return super().save(*args, **kwargs)

Check warning on line 43 in care/facility/models/events.py

View check run for this annotation

Codecov / codecov/patch

care/facility/models/events.py#L42-L43

Added lines #L42 - L43 were not covered by tests

def __str__(self) -> str:
return f"{self.model} - {self.name}"

Check warning on line 46 in care/facility/models/events.py

View check run for this annotation

Codecov / codecov/patch

care/facility/models/events.py#L46

Added line #L46 was not covered by tests


class PatientConsultationEvent(models.Model):
external_id = ULIDField(default=default, editable=False, unique=True)
external_id = ULIDField(default=ULID, editable=False, unique=True)
consultation = models.ForeignKey(
"PatientConsultation",
on_delete=models.PROTECT,
Expand All @@ -67,7 +68,7 @@
)

def __str__(self) -> str:
return f"{self.id} - {self.consultation_id} - {self.event_type} - {self.change_type}"

Check warning on line 71 in care/facility/models/events.py

View check run for this annotation

Codecov / codecov/patch

care/facility/models/events.py#L71

Added line #L71 was not covered by tests

class Meta:
ordering = ["-created_date"]
Expand Down
Empty file added care/utils/ulid/__init__.py
Empty file.
Loading
Loading