Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"inherited": false,
"de_novo": false,
"unknown_inheritance": false,
"publication": 2,
"is_deleted": 0
}
},
Expand All @@ -21,7 +20,6 @@
"inherited": false,
"de_novo": false,
"unknown_inheritance": true,
"publication": 2,
"is_deleted": 0
}
},
Expand All @@ -34,7 +32,6 @@
"inherited": false,
"de_novo": false,
"unknown_inheritance": false,
"publication": 1,
"is_deleted": 0
}
},
Expand All @@ -47,8 +44,31 @@
"inherited": false,
"de_novo": false,
"unknown_inheritance": false,
"publication": 2,
"is_deleted": 1
}
},
{
"model": "gene2phenotype_app.lgdvarianttype",
"pk": 5,
"fields": {
"lgd": 11,
"variant_type_ot": 13,
"inherited": false,
"de_novo": false,
"unknown_inheritance": false,
"is_deleted": 0
}
},
{
"model": "gene2phenotype_app.lgdvarianttype",
"pk": 6,
"fields": {
"lgd": 10,
"variant_type_ot": 13,
"inherited": false,
"de_novo": false,
"unknown_inheritance": false,
"is_deleted": 0
}
}
]
]
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,17 @@
"user": 1,
"date": "2025-05-03T11:38:52Z"
}
},
{
"model": "gene2phenotype_app.lgdvarianttypecomment",
"pk": 3,
"fields": {
"lgd_variant_type": 6,
"comment": "Comment only on the source record's variant type",
"is_public": 0,
"is_deleted": 0,
"user": 1,
"date": "2025-06-01T09:00:00Z"
}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
[
{
"model": "gene2phenotype_app.lgdvarianttypepublication",
"pk": 1,
"fields": {
"lgd_variant_type": 1,
"publication": 2,
"is_deleted": 0
}
},
{
"model": "gene2phenotype_app.lgdvarianttypepublication",
"pk": 2,
"fields": {
"lgd_variant_type": 2,
"publication": 2,
"is_deleted": 0
}
},
{
"model": "gene2phenotype_app.lgdvarianttypepublication",
"pk": 3,
"fields": {
"lgd_variant_type": 3,
"publication": 1,
"is_deleted": 0
}
},
{
"model": "gene2phenotype_app.lgdvarianttypepublication",
"pk": 4,
"fields": {
"lgd_variant_type": 4,
"publication": 2,
"is_deleted": 1
}
},
{
"model": "gene2phenotype_app.lgdvarianttypepublication",
"pk": 5,
"fields": {
"lgd_variant_type": 5,
"publication": 2,
"is_deleted": 0
}
},
{
"model": "gene2phenotype_app.lgdvarianttypepublication",
"pk": 6,
"fields": {
"lgd_variant_type": 6,
"publication": 1,
"is_deleted": 0
}
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -151,5 +151,39 @@
"is_reviewed": 1,
"is_deleted": 0
}
},
{
"model": "gene2phenotype_app.locusgenotypedisease",
"pk": 10,
"fields": {
"stable_id": 12,
"locus": 1,
"genotype": 9,
"disease": 6,
"mechanism": 1,
"mechanism_support": 17,
"confidence": 1,
"confidence_support": null,
"date_review": "2025-06-01T09:00:00Z",
"is_reviewed": 1,
"is_deleted": 0
}
},
{
"model": "gene2phenotype_app.locusgenotypedisease",
"pk": 11,
"fields": {
"stable_id": 13,
"locus": 1,
"genotype": 9,
"disease": 1,
"mechanism": 1,
"mechanism_support": 17,
"confidence": 1,
"confidence_support": null,
"date_review": "2025-06-01T09:00:00Z",
"is_reviewed": 1,
"is_deleted": 0
}
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@

from .MinedPublications import check_mined_publication_status

from .SimilarRecords import get_similar_records
from .SimilarRecords import get_similar_records, get_records_with_publication_overlap

from .DeletedRecords import check_deleted_records
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Generated by Django 5.2.14 on 2026-07-13 15:43

import django.db.models.deletion
import simple_history.models
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('gene2phenotype_app', '0020_remove_uniprotannotation_uniprot_ann_uniprot_c49c17_idx_and_more'),
]

operations = [
migrations.CreateModel(
name='HistoricalLGDVariantTypePublication',
fields=[
('id', models.IntegerField(blank=True, db_index=True)),
('is_deleted', models.SmallIntegerField(default=False)),
('history_id', models.AutoField(primary_key=True, serialize=False)),
('history_date', models.DateTimeField(db_index=True)),
('history_change_reason', models.CharField(max_length=100, null=True)),
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
('lgd_variant_type', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='gene2phenotype_app.lgdvarianttype')),
('publication', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='gene2phenotype_app.publication')),
],
options={
'verbose_name': 'historical lgd variant type publication',
'verbose_name_plural': 'historical lgd variant type publications',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': ('history_date', 'history_id'),
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name='LGDVariantTypePublication',
fields=[
('id', models.AutoField(primary_key=True, serialize=False)),
('is_deleted', models.SmallIntegerField(default=False)),
('lgd_variant_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='publications', to='gene2phenotype_app.lgdvarianttype')),
('publication', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='gene2phenotype_app.publication')),
],
options={
'db_table': 'lgd_variant_type_publication',
'unique_together': {('lgd_variant_type', 'publication')},
},
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from collections import defaultdict

from django.db import migrations


def populate_and_deduplicate(apps, schema_editor):
"""
LGDVariantType used to have a direct (nullable) publication FK, so the same
variant type got a separate row per supporting publication.
For each (lgd, variant_type_ot) group of rows:
- keep the earliest row as canonical
- copy every row's publication link into the new LGDVariantTypePublication join table
- re-point any comments from the surplus duplicate rows onto the canonical row
- merge the inherited/de_novo/unknown_inheritance flags (logical OR), matching the
merge semantics the API already applied when displaying these duplicates
- delete the surplus duplicate rows
"""
LGDVariantType = apps.get_model("gene2phenotype_app", "LGDVariantType")
LGDVariantTypePublication = apps.get_model(
"gene2phenotype_app", "LGDVariantTypePublication"
)
LGDVariantTypeComment = apps.get_model(
"gene2phenotype_app", "LGDVariantTypeComment"
)

groups = defaultdict(list)
for row in LGDVariantType.objects.all().order_by("id"):
groups[(row.lgd_id, row.variant_type_ot_id)].append(row)

for rows in groups.values():
canonical = rows[0]

for row in rows:
if row.publication_id:
LGDVariantTypePublication.objects.get_or_create(
lgd_variant_type_id=canonical.id,
publication_id=row.publication_id,
defaults={"is_deleted": row.is_deleted},
)

for row in rows[1:]:
LGDVariantTypeComment.objects.filter(lgd_variant_type_id=row.id).update(
lgd_variant_type_id=canonical.id
)
canonical.inherited = canonical.inherited or row.inherited
canonical.de_novo = canonical.de_novo or row.de_novo
canonical.unknown_inheritance = (
canonical.unknown_inheritance or row.unknown_inheritance
)
if row.is_deleted == 0:
canonical.is_deleted = 0
row.delete()

canonical.save()


def noop_reverse(apps, schema_editor):
pass


class Migration(migrations.Migration):

dependencies = [
("gene2phenotype_app", "0021_add_lgd_variant_type_publication"),
]

operations = [
migrations.RunPython(populate_and_deduplicate, noop_reverse),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 5.2.14 on 2026-07-13 15:43

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('gene2phenotype_app', '0022_populate_lgd_variant_type_publication'),
]

operations = [
migrations.RemoveField(
model_name='historicallgdvarianttype',
name='publication',
),
migrations.AlterUniqueTogether(
name='lgdvarianttype',
unique_together={('lgd', 'variant_type_ot')},
),
migrations.RemoveField(
model_name='lgdvarianttype',
name='publication',
),
]
27 changes: 23 additions & 4 deletions gene2phenotype_project/gene2phenotype_app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,10 +198,11 @@ class Meta:

class LGDVariantType(models.Model):
"""
Represents the variant type associated with the G2P record and a publication.
Represents the variant type associated with the G2P record.

Types of variants reported in the publication: missense_variant, frameshift_variant, stop_gained, etc.
Types of variants reported in publications: missense_variant, frameshift_variant, stop_gained, etc.
Sequence ontology terms are used to describe variant types.
A variant type can be supported by one or more publications - see LGDVariantTypePublication.
"""

id = models.AutoField(primary_key=True)
Expand All @@ -212,19 +213,37 @@ class LGDVariantType(models.Model):
inherited = models.BooleanField(default=False)
de_novo = models.BooleanField(default=False)
unknown_inheritance = models.BooleanField(default=False)
publication = models.ForeignKey("Publication", on_delete=models.PROTECT, null=True)
is_deleted = models.SmallIntegerField(null=False, default=False)
history = HistoricalRecords()

class Meta:
db_table = "lgd_variant_type"
unique_together = ["lgd", "variant_type_ot", "publication"]
unique_together = ["lgd", "variant_type_ot"]
indexes = [
models.Index(fields=["lgd", "variant_type_ot"]),
models.Index(fields=["variant_type_ot"]),
]


class LGDVariantTypePublication(models.Model):
"""
Links a LGDVariantType to the publication(s) that support it.
A single variant type can be evidenced by more than one publication.
"""

id = models.AutoField(primary_key=True)
lgd_variant_type = models.ForeignKey(
"LGDVariantType", related_name="publications", on_delete=models.PROTECT
)
publication = models.ForeignKey("Publication", on_delete=models.PROTECT)
is_deleted = models.SmallIntegerField(null=False, default=False)
history = HistoricalRecords()

class Meta:
db_table = "lgd_variant_type_publication"
unique_together = ["lgd_variant_type", "publication"]


class LGDVariantTypeDescription(models.Model):
"""
Represents the HGVS description linked to the LGD record and the publication.
Expand Down
Loading
Loading