From eee0a9d6bf64f337de2de4f6a3e9bc3853729839 Mon Sep 17 00:00:00 2001 From: Alex Wolf Date: Thu, 3 Jul 2025 22:00:38 +0200 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Improve=20records=20schema?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...input_of_runs_alter_record_run_and_more.py | 47 +++++++++++++++++++ lamindb/models/record.py | 19 ++++++-- lamindb/models/run.py | 10 ++++ 3 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 lamindb/migrations/0109_record_input_of_runs_alter_record_run_and_more.py diff --git a/lamindb/migrations/0109_record_input_of_runs_alter_record_run_and_more.py b/lamindb/migrations/0109_record_input_of_runs_alter_record_run_and_more.py new file mode 100644 index 000000000..3b74b3257 --- /dev/null +++ b/lamindb/migrations/0109_record_input_of_runs_alter_record_run_and_more.py @@ -0,0 +1,47 @@ +# Generated by Django 5.2 on 2025-07-03 19:59 + +import django.db.models.deletion +from django.db import migrations, models + +import lamindb.base.fields + + +class Migration(migrations.Migration): + dependencies = [ + ("lamindb", "0108_remove_record_sheet_remove_sheetproject_sheet_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="record", + name="input_of_runs", + field=models.ManyToManyField( + related_name="input_records", to="lamindb.run" + ), + ), + migrations.AlterField( + model_name="record", + name="run", + field=lamindb.base.fields.ForeignKey( + blank=True, + default=None, + editable=False, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="output_records", + to="lamindb.run", + ), + ), + migrations.AlterUniqueTogether( + name="recordrecord", + unique_together={("record", "feature", "value")}, + ), + migrations.AlterUniqueTogether( + name="recordrun", + unique_together={("record", "feature", "value")}, + ), + migrations.AlterUniqueTogether( + name="recordulabel", + unique_together={("record", "feature", "value")}, + ), + ] diff --git a/lamindb/models/record.py b/lamindb/models/record.py index 06ff66b70..6b1b7ff4b 100644 --- a/lamindb/models/record.py +++ b/lamindb/models/record.py @@ -95,6 +95,17 @@ class Meta(SQLRecord.Meta, TracksRun.Meta, TracksUpdates.Meta): """Linked artifacts.""" runs: Run = models.ManyToManyField(Run, through="RecordRun", related_name="records") """Linked runs.""" + run: Run | None = ForeignKey( + Run, + PROTECT, + related_name="output_records", + null=True, + default=None, + editable=False, + ) + """Run that created the record.""" + input_of_runs: Run = models.ManyToManyField(Run, related_name="input_records") + """Runs that use this record as an input.""" ulabels: ULabel = models.ManyToManyField( ULabel, through="RecordULabel", @@ -177,7 +188,7 @@ class RecordJson(BaseSQLRecord, IsLink): value: Any = JSONField(default=None, db_default=None) class Meta: - unique_together = ("record", "feature") + unique_together = ("record", "feature") # a list is modeled as a list in json class RecordRecord(SQLRecord, IsLink): @@ -191,7 +202,7 @@ class RecordRecord(SQLRecord, IsLink): ) # component class Meta: - unique_together = ("record", "feature") + unique_together = ("record", "feature", "value") class RecordULabel(BaseSQLRecord, IsLink): @@ -202,7 +213,7 @@ class RecordULabel(BaseSQLRecord, IsLink): class Meta: # allows linking exactly one record to one ulabel per feature, because we likely don't want to have Many - unique_together = ("record", "feature") + unique_together = ("record", "feature", "value") class RecordRun(BaseSQLRecord, IsLink): @@ -213,7 +224,7 @@ class RecordRun(BaseSQLRecord, IsLink): class Meta: # allows linking several records to a single run for the same feature because we'll likely need this - unique_together = ("record", "feature") + unique_together = ("record", "feature", "value") class RecordArtifact(BaseSQLRecord, IsLink): diff --git a/lamindb/models/run.py b/lamindb/models/run.py index 7607a92b9..89530596a 100644 --- a/lamindb/models/run.py +++ b/lamindb/models/run.py @@ -267,6 +267,16 @@ class Run(SQLRecord): Related accessor: via :attr:`~lamindb.Artifact.run` """ + input_records: Artifact + """The records serving as input for this run. + + Related accessor: :attr:`~lamindb.Record.input_of_runs`. + """ + output_records: Artifact + """The records generated by this run. + + Related accessor: via :attr:`~lamindb.Record.run` + """ input_collections: Collection """The collections serving as input for this run.""" output_collections: Collection