lamindb 1.1.0__py3-none-any.whl → 1.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lamindb/__init__.py +33 -26
- lamindb/_finish.py +9 -1
- lamindb/_tracked.py +26 -3
- lamindb/_view.py +2 -3
- lamindb/base/__init__.py +1 -1
- lamindb/base/ids.py +1 -10
- lamindb/base/users.py +1 -4
- lamindb/core/__init__.py +7 -65
- lamindb/core/_compat.py +60 -0
- lamindb/core/_context.py +50 -22
- lamindb/core/_mapped_collection.py +4 -2
- lamindb/core/_settings.py +6 -6
- lamindb/core/_sync_git.py +1 -1
- lamindb/core/_track_environment.py +2 -1
- lamindb/core/datasets/_small.py +3 -3
- lamindb/core/loaders.py +43 -20
- lamindb/core/storage/_anndata_accessor.py +8 -3
- lamindb/core/storage/_backed_access.py +14 -7
- lamindb/core/storage/_pyarrow_dataset.py +24 -9
- lamindb/core/storage/_tiledbsoma.py +8 -6
- lamindb/core/storage/_zarr.py +104 -25
- lamindb/core/storage/objects.py +63 -28
- lamindb/core/storage/paths.py +16 -13
- lamindb/core/types.py +10 -0
- lamindb/curators/__init__.py +176 -149
- lamindb/errors.py +1 -1
- lamindb/integrations/_vitessce.py +4 -4
- lamindb/migrations/0089_subsequent_runs.py +159 -0
- lamindb/migrations/0090_runproject_project_runs.py +73 -0
- lamindb/migrations/{0088_squashed.py → 0090_squashed.py} +245 -177
- lamindb/models/__init__.py +79 -0
- lamindb/{core → models}/_describe.py +3 -3
- lamindb/{core → models}/_django.py +8 -5
- lamindb/{core → models}/_feature_manager.py +103 -87
- lamindb/{_from_values.py → models/_from_values.py} +5 -2
- lamindb/{core/versioning.py → models/_is_versioned.py} +94 -6
- lamindb/{core → models}/_label_manager.py +10 -17
- lamindb/{core/relations.py → models/_relations.py} +8 -1
- lamindb/models/artifact.py +2602 -0
- lamindb/{_can_curate.py → models/can_curate.py} +349 -180
- lamindb/models/collection.py +683 -0
- lamindb/models/core.py +135 -0
- lamindb/models/feature.py +643 -0
- lamindb/models/flextable.py +163 -0
- lamindb/{_parents.py → models/has_parents.py} +55 -49
- lamindb/models/project.py +384 -0
- lamindb/{_query_manager.py → models/query_manager.py} +10 -8
- lamindb/{_query_set.py → models/query_set.py} +64 -32
- lamindb/models/record.py +1762 -0
- lamindb/models/run.py +563 -0
- lamindb/{_save.py → models/save.py} +18 -8
- lamindb/models/schema.py +732 -0
- lamindb/models/transform.py +360 -0
- lamindb/models/ulabel.py +249 -0
- {lamindb-1.1.0.dist-info → lamindb-1.2.0.dist-info}/METADATA +6 -6
- lamindb-1.2.0.dist-info/RECORD +95 -0
- lamindb/_artifact.py +0 -1361
- lamindb/_collection.py +0 -440
- lamindb/_feature.py +0 -316
- lamindb/_is_versioned.py +0 -40
- lamindb/_record.py +0 -1065
- lamindb/_run.py +0 -60
- lamindb/_schema.py +0 -347
- lamindb/_storage.py +0 -15
- lamindb/_transform.py +0 -170
- lamindb/_ulabel.py +0 -56
- lamindb/_utils.py +0 -9
- lamindb/base/validation.py +0 -63
- lamindb/core/_data.py +0 -491
- lamindb/core/fields.py +0 -12
- lamindb/models.py +0 -4435
- lamindb-1.1.0.dist-info/RECORD +0 -95
- {lamindb-1.1.0.dist-info → lamindb-1.2.0.dist-info}/LICENSE +0 -0
- {lamindb-1.1.0.dist-info → lamindb-1.2.0.dist-info}/WHEEL +0 -0
lamindb/errors.py
CHANGED
@@ -7,10 +7,10 @@ from typing import TYPE_CHECKING
|
|
7
7
|
import lamindb_setup as ln_setup
|
8
8
|
from lamin_utils import logger
|
9
9
|
|
10
|
-
from lamindb.
|
11
|
-
from lamindb.
|
12
|
-
from lamindb.
|
13
|
-
from lamindb.
|
10
|
+
from lamindb.models.artifact import Artifact
|
11
|
+
from lamindb.models.collection import Collection
|
12
|
+
from lamindb.models.run import Run
|
13
|
+
from lamindb.models.transform import Transform
|
14
14
|
|
15
15
|
if TYPE_CHECKING:
|
16
16
|
from vitessce import VitessceConfig
|
@@ -0,0 +1,159 @@
|
|
1
|
+
# ruff: noqa: S608
|
2
|
+
from django.db import migrations, models
|
3
|
+
|
4
|
+
|
5
|
+
def update_model_run_relationships(apps, schema_editor, model_name):
|
6
|
+
vendor = schema_editor.connection.vendor
|
7
|
+
|
8
|
+
# Define table names based on model_name
|
9
|
+
model_table = f"lamindb_{model_name}"
|
10
|
+
link_table = f"lamindb_{model_name}__previous_runs"
|
11
|
+
model_id_field = f"{model_name}_id"
|
12
|
+
|
13
|
+
with schema_editor.connection.cursor() as cursor:
|
14
|
+
# Step 1: Add the current run_id to the _previous_runs table if it doesn't exist
|
15
|
+
cursor.execute(f"""
|
16
|
+
INSERT INTO {link_table} ({model_id_field}, run_id)
|
17
|
+
SELECT a.id, a.run_id
|
18
|
+
FROM {model_table} a
|
19
|
+
WHERE a.run_id IS NOT NULL
|
20
|
+
AND NOT EXISTS (
|
21
|
+
SELECT 1
|
22
|
+
FROM {link_table} apr
|
23
|
+
WHERE apr.{model_id_field} = a.id
|
24
|
+
AND apr.run_id = a.run_id
|
25
|
+
);
|
26
|
+
""")
|
27
|
+
|
28
|
+
# Step 2: For each model, find the earliest run (lowest ID) and set it as the run_id
|
29
|
+
if vendor == "sqlite":
|
30
|
+
cursor.execute(f"""
|
31
|
+
UPDATE {model_table}
|
32
|
+
SET run_id = (
|
33
|
+
SELECT MIN(r.id)
|
34
|
+
FROM lamindb_run r
|
35
|
+
JOIN {link_table} apr ON r.id = apr.run_id
|
36
|
+
WHERE apr.{model_id_field} = {model_table}.id
|
37
|
+
)
|
38
|
+
WHERE EXISTS (
|
39
|
+
SELECT 1
|
40
|
+
FROM {link_table} apr
|
41
|
+
WHERE apr.{model_id_field} = {model_table}.id
|
42
|
+
);
|
43
|
+
""")
|
44
|
+
else: # PostgreSQL
|
45
|
+
cursor.execute(f"""
|
46
|
+
UPDATE {model_table} AS a
|
47
|
+
SET run_id = subquery.min_run_id
|
48
|
+
FROM (
|
49
|
+
SELECT {model_id_field}, MIN(run_id) as min_run_id
|
50
|
+
FROM {link_table}
|
51
|
+
GROUP BY {model_id_field}
|
52
|
+
) AS subquery
|
53
|
+
WHERE a.id = subquery.{model_id_field}
|
54
|
+
AND EXISTS (
|
55
|
+
SELECT 1
|
56
|
+
FROM {link_table} apr
|
57
|
+
WHERE apr.{model_id_field} = a.id
|
58
|
+
);
|
59
|
+
""")
|
60
|
+
|
61
|
+
# Step 3: Remove the earliest run from the link table
|
62
|
+
if vendor == "sqlite":
|
63
|
+
cursor.execute(f"""
|
64
|
+
DELETE FROM {link_table}
|
65
|
+
WHERE EXISTS (
|
66
|
+
SELECT 1 FROM {model_table} a
|
67
|
+
WHERE {link_table}.{model_id_field} = a.id
|
68
|
+
AND {link_table}.run_id = a.run_id
|
69
|
+
);
|
70
|
+
""")
|
71
|
+
else: # PostgreSQL
|
72
|
+
cursor.execute(f"""
|
73
|
+
DELETE FROM {link_table} AS apr
|
74
|
+
USING {model_table} AS a
|
75
|
+
WHERE apr.{model_id_field} = a.id
|
76
|
+
AND apr.run_id = a.run_id;
|
77
|
+
""")
|
78
|
+
|
79
|
+
|
80
|
+
def update_artifact_run_relationships(apps, schema_editor):
|
81
|
+
"""Migration function for artifacts."""
|
82
|
+
update_model_run_relationships(apps, schema_editor, "artifact")
|
83
|
+
|
84
|
+
|
85
|
+
def update_collection_run_relationships(apps, schema_editor):
|
86
|
+
"""Migration function for collections."""
|
87
|
+
update_model_run_relationships(apps, schema_editor, "collection")
|
88
|
+
|
89
|
+
|
90
|
+
class Migration(migrations.Migration):
|
91
|
+
dependencies = [
|
92
|
+
("lamindb", "0088_schema_components"),
|
93
|
+
]
|
94
|
+
|
95
|
+
operations = [
|
96
|
+
# unrelated to subsequent runs, but related to lamindb 1.2
|
97
|
+
# update the otype field in the artifact table
|
98
|
+
migrations.RunSQL(
|
99
|
+
sql="""
|
100
|
+
UPDATE lamindb_artifact
|
101
|
+
SET otype = 'SpatialData'
|
102
|
+
WHERE otype = 'spatialdata';
|
103
|
+
"""
|
104
|
+
),
|
105
|
+
# Migrate artifact relationships
|
106
|
+
migrations.RunPython(
|
107
|
+
update_artifact_run_relationships, migrations.RunPython.noop
|
108
|
+
),
|
109
|
+
# Update artifact model state
|
110
|
+
migrations.SeparateDatabaseAndState(
|
111
|
+
# Database operations (none, to keep tables intact)
|
112
|
+
[],
|
113
|
+
# State operations (to update Django model only)
|
114
|
+
[
|
115
|
+
# Remove the old field from model state
|
116
|
+
migrations.RemoveField(
|
117
|
+
model_name="artifact",
|
118
|
+
name="_previous_runs",
|
119
|
+
),
|
120
|
+
# Add the new field with the same underlying table
|
121
|
+
migrations.AddField(
|
122
|
+
model_name="artifact",
|
123
|
+
name="_subsequent_runs",
|
124
|
+
field=models.ManyToManyField(
|
125
|
+
"lamindb.run",
|
126
|
+
related_name="_recreated_artifacts",
|
127
|
+
db_table="lamindb_artifact__previous_runs", # Keep the original table name
|
128
|
+
),
|
129
|
+
),
|
130
|
+
],
|
131
|
+
),
|
132
|
+
# Migrate collection relationships
|
133
|
+
migrations.RunPython(
|
134
|
+
update_collection_run_relationships, migrations.RunPython.noop
|
135
|
+
),
|
136
|
+
# Update collection model state
|
137
|
+
migrations.SeparateDatabaseAndState(
|
138
|
+
# Database operations (none, to keep tables intact)
|
139
|
+
[],
|
140
|
+
# State operations (to update Django model only)
|
141
|
+
[
|
142
|
+
# Remove the old field from model state
|
143
|
+
migrations.RemoveField(
|
144
|
+
model_name="collection",
|
145
|
+
name="_previous_runs",
|
146
|
+
),
|
147
|
+
# Add the new field with the same underlying table
|
148
|
+
migrations.AddField(
|
149
|
+
model_name="collection",
|
150
|
+
name="_subsequent_runs",
|
151
|
+
field=models.ManyToManyField(
|
152
|
+
"lamindb.run",
|
153
|
+
related_name="_recreated_collections",
|
154
|
+
db_table="lamindb_collection__previous_runs", # Keep the original table name
|
155
|
+
),
|
156
|
+
),
|
157
|
+
],
|
158
|
+
),
|
159
|
+
]
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# Generated by Django 5.2 on 2025-03-05 10:20
|
2
|
+
|
3
|
+
import django.db.models.deletion
|
4
|
+
import django.db.models.functions.datetime
|
5
|
+
from django.db import migrations, models
|
6
|
+
|
7
|
+
import lamindb.base.fields
|
8
|
+
import lamindb.base.users
|
9
|
+
import lamindb.models.record
|
10
|
+
|
11
|
+
|
12
|
+
class Migration(migrations.Migration):
|
13
|
+
dependencies = [
|
14
|
+
("lamindb", "0089_subsequent_runs"),
|
15
|
+
]
|
16
|
+
|
17
|
+
operations = [
|
18
|
+
migrations.CreateModel(
|
19
|
+
name="RunProject",
|
20
|
+
fields=[
|
21
|
+
("id", models.BigAutoField(primary_key=True, serialize=False)),
|
22
|
+
(
|
23
|
+
"created_at",
|
24
|
+
lamindb.base.fields.DateTimeField(
|
25
|
+
blank=True,
|
26
|
+
db_default=django.db.models.functions.datetime.Now(),
|
27
|
+
db_index=True,
|
28
|
+
editable=False,
|
29
|
+
),
|
30
|
+
),
|
31
|
+
(
|
32
|
+
"created_by",
|
33
|
+
lamindb.base.fields.ForeignKey(
|
34
|
+
blank=True,
|
35
|
+
default=lamindb.base.users.current_user_id,
|
36
|
+
editable=False,
|
37
|
+
on_delete=django.db.models.deletion.PROTECT,
|
38
|
+
related_name="+",
|
39
|
+
to="lamindb.user",
|
40
|
+
),
|
41
|
+
),
|
42
|
+
(
|
43
|
+
"project",
|
44
|
+
lamindb.base.fields.ForeignKey(
|
45
|
+
blank=True,
|
46
|
+
on_delete=django.db.models.deletion.PROTECT,
|
47
|
+
related_name="links_run",
|
48
|
+
to="lamindb.project",
|
49
|
+
),
|
50
|
+
),
|
51
|
+
(
|
52
|
+
"run",
|
53
|
+
lamindb.base.fields.ForeignKey(
|
54
|
+
blank=True,
|
55
|
+
on_delete=django.db.models.deletion.CASCADE,
|
56
|
+
related_name="links_project",
|
57
|
+
to="lamindb.run",
|
58
|
+
),
|
59
|
+
),
|
60
|
+
],
|
61
|
+
options={
|
62
|
+
"unique_together": {("run", "project")},
|
63
|
+
},
|
64
|
+
bases=(models.Model, lamindb.models.record.LinkORM),
|
65
|
+
),
|
66
|
+
migrations.AddField(
|
67
|
+
model_name="project",
|
68
|
+
name="runs",
|
69
|
+
field=models.ManyToManyField(
|
70
|
+
related_name="projects", through="lamindb.RunProject", to="lamindb.run"
|
71
|
+
),
|
72
|
+
),
|
73
|
+
]
|