lamindb 1.10.1__py3-none-any.whl → 1.11.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 +89 -49
- lamindb/_finish.py +17 -15
- lamindb/_tracked.py +2 -4
- lamindb/_view.py +1 -1
- lamindb/base/__init__.py +2 -1
- lamindb/base/dtypes.py +76 -0
- lamindb/core/_settings.py +45 -2
- lamindb/core/storage/_anndata_accessor.py +118 -26
- lamindb/core/storage/_backed_access.py +10 -7
- lamindb/core/storage/_spatialdata_accessor.py +15 -4
- lamindb/core/storage/_zarr.py +3 -0
- lamindb/curators/_legacy.py +16 -3
- lamindb/curators/core.py +449 -193
- lamindb/errors.py +6 -0
- lamindb/examples/cellxgene/__init__.py +8 -3
- lamindb/examples/cellxgene/_cellxgene.py +127 -13
- lamindb/examples/cellxgene/{cxg_schema_versions.csv → cellxgene_schema_versions.csv} +11 -0
- lamindb/examples/croissant/__init__.py +32 -6
- lamindb/examples/datasets/__init__.py +2 -2
- lamindb/examples/datasets/_core.py +9 -2
- lamindb/examples/datasets/_small.py +66 -22
- lamindb/examples/fixtures/sheets.py +8 -2
- lamindb/integrations/_croissant.py +34 -11
- lamindb/migrations/0118_alter_recordproject_value_projectrecord.py +99 -0
- lamindb/migrations/0119_rename_records_project_linked_in_records.py +26 -0
- lamindb/migrations/{0117_squashed.py → 0119_squashed.py} +92 -5
- lamindb/migrations/0120_add_record_fk_constraint.py +64 -0
- lamindb/migrations/0121_recorduser.py +60 -0
- lamindb/models/__init__.py +4 -1
- lamindb/models/_describe.py +2 -2
- lamindb/models/_feature_manager.py +131 -71
- lamindb/models/_from_values.py +2 -2
- lamindb/models/_is_versioned.py +4 -4
- lamindb/models/_label_manager.py +4 -4
- lamindb/models/artifact.py +357 -192
- lamindb/models/artifact_set.py +45 -1
- lamindb/models/can_curate.py +1 -2
- lamindb/models/collection.py +3 -34
- lamindb/models/feature.py +111 -7
- lamindb/models/has_parents.py +11 -11
- lamindb/models/project.py +42 -2
- lamindb/models/query_manager.py +16 -7
- lamindb/models/query_set.py +191 -78
- lamindb/models/record.py +30 -5
- lamindb/models/run.py +10 -33
- lamindb/models/save.py +6 -8
- lamindb/models/schema.py +54 -26
- lamindb/models/sqlrecord.py +152 -40
- lamindb/models/storage.py +59 -14
- lamindb/models/transform.py +17 -17
- lamindb/models/ulabel.py +6 -1
- {lamindb-1.10.1.dist-info → lamindb-1.11.0.dist-info}/METADATA +11 -16
- {lamindb-1.10.1.dist-info → lamindb-1.11.0.dist-info}/RECORD +55 -50
- {lamindb-1.10.1.dist-info → lamindb-1.11.0.dist-info}/LICENSE +0 -0
- {lamindb-1.10.1.dist-info → lamindb-1.11.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,99 @@
|
|
1
|
+
# Generated by Django 5.2 on 2025-08-07 15:28
|
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.run
|
10
|
+
import lamindb.models.sqlrecord
|
11
|
+
|
12
|
+
|
13
|
+
class Migration(migrations.Migration):
|
14
|
+
dependencies = [
|
15
|
+
("lamindb", "0117_fix_artifact_storage_hash_unique_constraints"),
|
16
|
+
]
|
17
|
+
|
18
|
+
operations = [
|
19
|
+
migrations.AlterField(
|
20
|
+
model_name="recordproject",
|
21
|
+
name="value",
|
22
|
+
field=lamindb.base.fields.ForeignKey(
|
23
|
+
blank=True,
|
24
|
+
on_delete=django.db.models.deletion.PROTECT,
|
25
|
+
related_name="links_in_record",
|
26
|
+
to="lamindb.project",
|
27
|
+
),
|
28
|
+
),
|
29
|
+
migrations.CreateModel(
|
30
|
+
name="ProjectRecord",
|
31
|
+
fields=[
|
32
|
+
(
|
33
|
+
"created_at",
|
34
|
+
lamindb.base.fields.DateTimeField(
|
35
|
+
blank=True,
|
36
|
+
db_default=django.db.models.functions.datetime.Now(),
|
37
|
+
db_index=True,
|
38
|
+
editable=False,
|
39
|
+
),
|
40
|
+
),
|
41
|
+
("id", models.BigAutoField(primary_key=True, serialize=False)),
|
42
|
+
(
|
43
|
+
"created_by",
|
44
|
+
lamindb.base.fields.ForeignKey(
|
45
|
+
blank=True,
|
46
|
+
default=lamindb.base.users.current_user_id,
|
47
|
+
editable=False,
|
48
|
+
on_delete=django.db.models.deletion.PROTECT,
|
49
|
+
related_name="+",
|
50
|
+
to="lamindb.user",
|
51
|
+
),
|
52
|
+
),
|
53
|
+
(
|
54
|
+
"feature",
|
55
|
+
lamindb.base.fields.ForeignKey(
|
56
|
+
blank=True,
|
57
|
+
default=None,
|
58
|
+
null=True,
|
59
|
+
on_delete=django.db.models.deletion.PROTECT,
|
60
|
+
related_name="links_projectrecord",
|
61
|
+
to="lamindb.feature",
|
62
|
+
),
|
63
|
+
),
|
64
|
+
(
|
65
|
+
"project",
|
66
|
+
lamindb.base.fields.ForeignKey(
|
67
|
+
blank=True,
|
68
|
+
on_delete=django.db.models.deletion.PROTECT,
|
69
|
+
related_name="links_record",
|
70
|
+
to="lamindb.project",
|
71
|
+
),
|
72
|
+
),
|
73
|
+
(
|
74
|
+
"record",
|
75
|
+
lamindb.base.fields.ForeignKey(
|
76
|
+
blank=True,
|
77
|
+
on_delete=django.db.models.deletion.CASCADE,
|
78
|
+
related_name="links_project",
|
79
|
+
to="lamindb.record",
|
80
|
+
),
|
81
|
+
),
|
82
|
+
(
|
83
|
+
"run",
|
84
|
+
lamindb.base.fields.ForeignKey(
|
85
|
+
blank=True,
|
86
|
+
default=lamindb.models.run.current_run,
|
87
|
+
null=True,
|
88
|
+
on_delete=django.db.models.deletion.PROTECT,
|
89
|
+
related_name="+",
|
90
|
+
to="lamindb.run",
|
91
|
+
),
|
92
|
+
),
|
93
|
+
],
|
94
|
+
options={
|
95
|
+
"unique_together": {("record", "project", "feature")},
|
96
|
+
},
|
97
|
+
bases=(lamindb.models.sqlrecord.IsLink, models.Model),
|
98
|
+
),
|
99
|
+
]
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Generated by Django 5.2 on 2025-08-09 13:31
|
2
|
+
|
3
|
+
from django.db import migrations, models
|
4
|
+
|
5
|
+
|
6
|
+
class Migration(migrations.Migration):
|
7
|
+
dependencies = [
|
8
|
+
("lamindb", "0118_alter_recordproject_value_projectrecord"),
|
9
|
+
]
|
10
|
+
|
11
|
+
operations = [
|
12
|
+
migrations.RenameField(
|
13
|
+
model_name="project",
|
14
|
+
old_name="records",
|
15
|
+
new_name="linked_in_records",
|
16
|
+
),
|
17
|
+
migrations.AddField(
|
18
|
+
model_name="project",
|
19
|
+
name="records",
|
20
|
+
field=models.ManyToManyField(
|
21
|
+
related_name="projects",
|
22
|
+
through="lamindb.ProjectRecord",
|
23
|
+
to="lamindb.record",
|
24
|
+
),
|
25
|
+
),
|
26
|
+
]
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Generated by Django 5.2 on 2025-
|
1
|
+
# Generated by Django 5.2 on 2025-08-09 13:33
|
2
2
|
|
3
3
|
import django.core.validators
|
4
4
|
import django.db.models.deletion
|
@@ -139,6 +139,8 @@ class Migration(migrations.Migration):
|
|
139
139
|
("lamindb", "0115_alter_space_uid"),
|
140
140
|
("lamindb", "0116_remove_artifact_unique_artifact_storage_key_hash_and_more"),
|
141
141
|
("lamindb", "0117_fix_artifact_storage_hash_unique_constraints"),
|
142
|
+
("lamindb", "0118_alter_recordproject_value_projectrecord"),
|
143
|
+
("lamindb", "0119_rename_records_project_linked_in_records"),
|
142
144
|
]
|
143
145
|
|
144
146
|
dependencies = [] # type: ignore
|
@@ -217,9 +219,8 @@ class Migration(migrations.Migration):
|
|
217
219
|
"uid",
|
218
220
|
lamindb.base.fields.CharField(
|
219
221
|
blank=True,
|
220
|
-
db_default="aaaaaaaaaaaa",
|
221
222
|
db_index=True,
|
222
|
-
default=
|
223
|
+
default=lamindb.base.uids.base62_12,
|
223
224
|
editable=False,
|
224
225
|
max_length=12,
|
225
226
|
unique=True,
|
@@ -1522,6 +1523,60 @@ class Migration(migrations.Migration):
|
|
1522
1523
|
},
|
1523
1524
|
bases=(lamindb.models.can_curate.CanCurate, models.Model),
|
1524
1525
|
),
|
1526
|
+
migrations.CreateModel(
|
1527
|
+
name="ProjectRecord",
|
1528
|
+
fields=[
|
1529
|
+
(
|
1530
|
+
"created_at",
|
1531
|
+
lamindb.base.fields.DateTimeField(
|
1532
|
+
blank=True,
|
1533
|
+
db_default=django.db.models.functions.datetime.Now(),
|
1534
|
+
db_index=True,
|
1535
|
+
editable=False,
|
1536
|
+
),
|
1537
|
+
),
|
1538
|
+
("id", models.BigAutoField(primary_key=True, serialize=False)),
|
1539
|
+
(
|
1540
|
+
"feature",
|
1541
|
+
lamindb.base.fields.ForeignKey(
|
1542
|
+
blank=True,
|
1543
|
+
default=None,
|
1544
|
+
null=True,
|
1545
|
+
on_delete=django.db.models.deletion.PROTECT,
|
1546
|
+
related_name="links_projectrecord",
|
1547
|
+
to="lamindb.feature",
|
1548
|
+
),
|
1549
|
+
),
|
1550
|
+
(
|
1551
|
+
"project",
|
1552
|
+
lamindb.base.fields.ForeignKey(
|
1553
|
+
blank=True,
|
1554
|
+
on_delete=django.db.models.deletion.PROTECT,
|
1555
|
+
related_name="links_record",
|
1556
|
+
to="lamindb.project",
|
1557
|
+
),
|
1558
|
+
),
|
1559
|
+
(
|
1560
|
+
"record",
|
1561
|
+
lamindb.base.fields.ForeignKey(
|
1562
|
+
blank=True,
|
1563
|
+
on_delete=django.db.models.deletion.CASCADE,
|
1564
|
+
related_name="links_project",
|
1565
|
+
to="lamindb.record",
|
1566
|
+
),
|
1567
|
+
),
|
1568
|
+
],
|
1569
|
+
bases=(lamindb.models.sqlrecord.IsLink, models.Model),
|
1570
|
+
),
|
1571
|
+
migrations.AddField(
|
1572
|
+
model_name="project",
|
1573
|
+
name="records",
|
1574
|
+
field=models.ManyToManyField(
|
1575
|
+
related_name="projects",
|
1576
|
+
through="lamindb.ProjectRecord",
|
1577
|
+
to="lamindb.record",
|
1578
|
+
),
|
1579
|
+
),
|
1525
1580
|
migrations.AddField(
|
1526
1581
|
model_name="artifactrecord",
|
1527
1582
|
name="record",
|
@@ -1651,7 +1706,7 @@ class Migration(migrations.Migration):
|
|
1651
1706
|
lamindb.base.fields.ForeignKey(
|
1652
1707
|
blank=True,
|
1653
1708
|
on_delete=django.db.models.deletion.PROTECT,
|
1654
|
-
related_name="
|
1709
|
+
related_name="links_in_record",
|
1655
1710
|
to="lamindb.project",
|
1656
1711
|
),
|
1657
1712
|
),
|
@@ -1663,7 +1718,7 @@ class Migration(migrations.Migration):
|
|
1663
1718
|
),
|
1664
1719
|
migrations.AddField(
|
1665
1720
|
model_name="project",
|
1666
|
-
name="
|
1721
|
+
name="linked_in_records",
|
1667
1722
|
field=models.ManyToManyField(
|
1668
1723
|
related_name="linked_projects",
|
1669
1724
|
through="lamindb.RecordProject",
|
@@ -2198,6 +2253,18 @@ class Migration(migrations.Migration):
|
|
2198
2253
|
to="lamindb.run",
|
2199
2254
|
),
|
2200
2255
|
),
|
2256
|
+
migrations.AddField(
|
2257
|
+
model_name="projectrecord",
|
2258
|
+
name="run",
|
2259
|
+
field=lamindb.base.fields.ForeignKey(
|
2260
|
+
blank=True,
|
2261
|
+
default=lamindb.models.run.current_run,
|
2262
|
+
null=True,
|
2263
|
+
on_delete=django.db.models.deletion.PROTECT,
|
2264
|
+
related_name="+",
|
2265
|
+
to="lamindb.run",
|
2266
|
+
),
|
2267
|
+
),
|
2201
2268
|
migrations.AddField(
|
2202
2269
|
model_name="project",
|
2203
2270
|
name="run",
|
@@ -4174,6 +4241,18 @@ class Migration(migrations.Migration):
|
|
4174
4241
|
to="lamindb.user",
|
4175
4242
|
),
|
4176
4243
|
),
|
4244
|
+
migrations.AddField(
|
4245
|
+
model_name="projectrecord",
|
4246
|
+
name="created_by",
|
4247
|
+
field=lamindb.base.fields.ForeignKey(
|
4248
|
+
blank=True,
|
4249
|
+
default=lamindb.base.users.current_user_id,
|
4250
|
+
editable=False,
|
4251
|
+
on_delete=django.db.models.deletion.PROTECT,
|
4252
|
+
related_name="+",
|
4253
|
+
to="lamindb.user",
|
4254
|
+
),
|
4255
|
+
),
|
4177
4256
|
migrations.AddField(
|
4178
4257
|
model_name="project",
|
4179
4258
|
name="created_by",
|
@@ -4427,6 +4506,10 @@ class Migration(migrations.Migration):
|
|
4427
4506
|
name="runfeaturevalue",
|
4428
4507
|
unique_together={("run", "featurevalue")},
|
4429
4508
|
),
|
4509
|
+
migrations.AlterUniqueTogether(
|
4510
|
+
name="projectrecord",
|
4511
|
+
unique_together={("record", "project", "feature")},
|
4512
|
+
),
|
4430
4513
|
migrations.AlterUniqueTogether(
|
4431
4514
|
name="personproject",
|
4432
4515
|
unique_together={("person", "project")},
|
@@ -4498,4 +4581,8 @@ class Migration(migrations.Migration):
|
|
4498
4581
|
name="unique_artifact_storage_hash_null_key",
|
4499
4582
|
),
|
4500
4583
|
),
|
4584
|
+
migrations.AlterModelOptions(
|
4585
|
+
name="user",
|
4586
|
+
options={},
|
4587
|
+
),
|
4501
4588
|
]
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# Generated by Django 5.2 on 2025-08-07 18:52
|
2
|
+
|
3
|
+
from django.db import migrations
|
4
|
+
|
5
|
+
CREATE_FUNCTION_SQL = """
|
6
|
+
CREATE OR REPLACE FUNCTION is_valid_record_type(record_type_id INTEGER, record_is_type BOOLEAN)
|
7
|
+
RETURNS BOOLEAN AS $$
|
8
|
+
BEGIN
|
9
|
+
-- Record with no type is valid
|
10
|
+
IF record_type_id IS NULL THEN
|
11
|
+
RETURN TRUE;
|
12
|
+
END IF;
|
13
|
+
|
14
|
+
-- If current record is a type, it can only reference schema-less types
|
15
|
+
IF record_is_type THEN
|
16
|
+
RETURN EXISTS (
|
17
|
+
SELECT 1 FROM lamindb_record r
|
18
|
+
WHERE r.id = record_type_id AND r.is_type AND r.schema_id IS NULL
|
19
|
+
);
|
20
|
+
END IF;
|
21
|
+
|
22
|
+
-- Regular records can reference any type
|
23
|
+
RETURN EXISTS (
|
24
|
+
SELECT 1 FROM lamindb_record r
|
25
|
+
WHERE r.id = record_type_id AND r.is_type
|
26
|
+
);
|
27
|
+
END;
|
28
|
+
$$ LANGUAGE plpgsql;
|
29
|
+
"""
|
30
|
+
|
31
|
+
ADD_CONSTRAINT_SQL = """
|
32
|
+
ALTER TABLE lamindb_record
|
33
|
+
ADD CONSTRAINT record_type_is_valid_fk
|
34
|
+
CHECK (is_valid_record_type(type_id, is_type));
|
35
|
+
"""
|
36
|
+
|
37
|
+
DROP_CONSTRAINT_SQL = (
|
38
|
+
"ALTER TABLE lamindb_record DROP CONSTRAINT IF EXISTS record_type_is_valid_fk;"
|
39
|
+
)
|
40
|
+
DROP_FUNCTION_SQL = "DROP FUNCTION IF EXISTS is_valid_record_type(INTEGER, BOOLEAN);"
|
41
|
+
|
42
|
+
|
43
|
+
def apply_postgres_constraint(apps, schema_editor):
|
44
|
+
if schema_editor.connection.vendor == "postgresql":
|
45
|
+
schema_editor.execute(CREATE_FUNCTION_SQL)
|
46
|
+
schema_editor.execute(ADD_CONSTRAINT_SQL)
|
47
|
+
|
48
|
+
|
49
|
+
def revert_postgres_constraint(apps, schema_editor):
|
50
|
+
if schema_editor.connection.vendor == "postgresql":
|
51
|
+
schema_editor.execute(DROP_CONSTRAINT_SQL)
|
52
|
+
schema_editor.execute(DROP_FUNCTION_SQL)
|
53
|
+
|
54
|
+
|
55
|
+
class Migration(migrations.Migration):
|
56
|
+
dependencies = [
|
57
|
+
("lamindb", "0119_squashed"),
|
58
|
+
]
|
59
|
+
|
60
|
+
operations = [
|
61
|
+
migrations.RunPython(
|
62
|
+
apply_postgres_constraint, reverse_code=revert_postgres_constraint
|
63
|
+
),
|
64
|
+
]
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# Generated by Django 5.2 on 2025-09-05 12:25
|
2
|
+
|
3
|
+
import django.db.models.deletion
|
4
|
+
from django.db import migrations, models
|
5
|
+
|
6
|
+
import lamindb.base.fields
|
7
|
+
import lamindb.models.sqlrecord
|
8
|
+
|
9
|
+
|
10
|
+
class Migration(migrations.Migration):
|
11
|
+
dependencies = [
|
12
|
+
("lamindb", "0120_add_record_fk_constraint"),
|
13
|
+
]
|
14
|
+
|
15
|
+
operations = [
|
16
|
+
migrations.CreateModel(
|
17
|
+
name="RecordUser",
|
18
|
+
fields=[
|
19
|
+
("id", models.BigAutoField(primary_key=True, serialize=False)),
|
20
|
+
(
|
21
|
+
"feature",
|
22
|
+
lamindb.base.fields.ForeignKey(
|
23
|
+
blank=True,
|
24
|
+
on_delete=django.db.models.deletion.PROTECT,
|
25
|
+
related_name="links_recorduser",
|
26
|
+
to="lamindb.feature",
|
27
|
+
),
|
28
|
+
),
|
29
|
+
(
|
30
|
+
"record",
|
31
|
+
lamindb.base.fields.ForeignKey(
|
32
|
+
blank=True,
|
33
|
+
on_delete=django.db.models.deletion.CASCADE,
|
34
|
+
related_name="values_user",
|
35
|
+
to="lamindb.record",
|
36
|
+
),
|
37
|
+
),
|
38
|
+
(
|
39
|
+
"value",
|
40
|
+
lamindb.base.fields.ForeignKey(
|
41
|
+
blank=True,
|
42
|
+
on_delete=django.db.models.deletion.PROTECT,
|
43
|
+
related_name="links_record",
|
44
|
+
to="lamindb.user",
|
45
|
+
),
|
46
|
+
),
|
47
|
+
],
|
48
|
+
options={
|
49
|
+
"unique_together": {("record", "feature", "value")},
|
50
|
+
},
|
51
|
+
bases=(models.Model, lamindb.models.sqlrecord.IsLink),
|
52
|
+
),
|
53
|
+
migrations.AddField(
|
54
|
+
model_name="record",
|
55
|
+
name="linked_users",
|
56
|
+
field=models.ManyToManyField(
|
57
|
+
related_name="records", through="lamindb.RecordUser", to="lamindb.user"
|
58
|
+
),
|
59
|
+
),
|
60
|
+
]
|
lamindb/models/__init__.py
CHANGED
@@ -9,6 +9,7 @@
|
|
9
9
|
BasicQuerySet
|
10
10
|
QuerySet
|
11
11
|
ArtifactSet
|
12
|
+
LazyArtifact
|
12
13
|
QueryManager
|
13
14
|
SQLRecordList
|
14
15
|
FeatureManager
|
@@ -49,7 +50,7 @@ from .schema import Schema
|
|
49
50
|
from .ulabel import ULabel
|
50
51
|
|
51
52
|
# should come last as it needs everything else
|
52
|
-
from .artifact import Artifact
|
53
|
+
from .artifact import Artifact, LazyArtifact
|
53
54
|
from ._feature_manager import FeatureManager
|
54
55
|
from ._label_manager import LabelManager
|
55
56
|
from .collection import Collection, CollectionArtifact
|
@@ -78,6 +79,7 @@ from .project import (
|
|
78
79
|
PersonProject,
|
79
80
|
RecordPerson,
|
80
81
|
RecordReference,
|
82
|
+
ProjectRecord,
|
81
83
|
)
|
82
84
|
from .run import RunFeatureValue
|
83
85
|
from .schema import (
|
@@ -94,6 +96,7 @@ from .record import (
|
|
94
96
|
RecordRecord,
|
95
97
|
RecordULabel,
|
96
98
|
RecordRun,
|
99
|
+
RecordUser,
|
97
100
|
RecordArtifact,
|
98
101
|
ArtifactRecord,
|
99
102
|
)
|
lamindb/models/_describe.py
CHANGED
@@ -8,8 +8,6 @@ from lamin_utils import logger
|
|
8
8
|
from rich.text import Text
|
9
9
|
from rich.tree import Tree
|
10
10
|
|
11
|
-
from ..core._context import is_run_from_ipython
|
12
|
-
|
13
11
|
if TYPE_CHECKING:
|
14
12
|
from lamindb.models import Artifact, Collection, Run
|
15
13
|
|
@@ -41,6 +39,8 @@ def format_rich_tree(
|
|
41
39
|
) -> str | None:
|
42
40
|
from rich.console import Console
|
43
41
|
|
42
|
+
from ..core._context import is_run_from_ipython
|
43
|
+
|
44
44
|
# If tree has no children, return fallback
|
45
45
|
if not tree.children:
|
46
46
|
return fallback
|