membershipworks: Avoid duplicating Transactions with NULL sid field
All checks were successful
Ruff / ruff (push) Successful in 58s
Test / test (push) Successful in 3m56s

Treat NULL in Transaction.sid as non-distinct in the UNIQUE constraint
This commit is contained in:
Adam Goldsmith 2024-12-06 15:06:41 -05:00
parent 01c469b0ce
commit 431dfb723b
2 changed files with 52 additions and 1 deletions

View File

@ -0,0 +1,47 @@
# Generated by Django 5.1.4 on 2024-12-06 19:44
import itertools
from django.db import migrations, models
def remove_duplicates(apps, schema_editor):
Transaction = apps.get_model("membershipworks", "Transaction")
for _, group in itertools.groupby(
Transaction.objects.filter(sid=None).order_by("timestamp"),
key=lambda t: t.timestamp,
):
dupes = list(group)
first_in_group = dupes.pop()
for t in dupes:
if any(
getattr(t, field.name) != getattr(first_in_group, field.name)
for field in Transaction._meta.get_fields()
if field.name != "id"
):
raise Exception("Transaction doesn't match!")
t.delete()
class Migration(migrations.Migration):
dependencies = [
("membershipworks", "0005_historicalmember_nfc_card_number_and_more"),
]
operations = [
migrations.RunPython(
remove_duplicates, reverse_code=migrations.RunPython.noop, atomic=True
),
migrations.RemoveConstraint(
model_name="transaction",
name="unique_sid_timestamp",
),
migrations.AddConstraint(
model_name="transaction",
constraint=models.UniqueConstraint(
fields=("sid", "timestamp"),
name="unique_sid_timestamp",
nulls_distinct=False,
),
),
]

View File

@ -377,7 +377,11 @@ class Transaction(BaseModel):
class Meta: class Meta:
db_table = "transactions" db_table = "transactions"
constraints = [ constraints = [
models.UniqueConstraint("sid", "timestamp", name="unique_sid_timestamp") models.UniqueConstraint(
fields=["sid", "timestamp"],
name="unique_sid_timestamp",
nulls_distinct=False,
)
] ]
def __str__(self): def __str__(self):