lamindb 0.76.12__py3-none-any.whl → 0.76.13__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 +1 -1
- lamindb/_artifact.py +4 -3
- lamindb/_collection.py +6 -5
- lamindb/_feature_set.py +3 -1
- lamindb/_parents.py +18 -3
- lamindb/_query_manager.py +0 -15
- lamindb/_query_set.py +1 -1
- lamindb/_record.py +6 -4
- lamindb/core/_context.py +1 -1
- lamindb/core/_django.py +19 -5
- lamindb/core/_feature_manager.py +4 -2
- lamindb/core/_label_manager.py +70 -93
- lamindb/core/schema.py +42 -3
- {lamindb-0.76.12.dist-info → lamindb-0.76.13.dist-info}/METADATA +2 -2
- {lamindb-0.76.12.dist-info → lamindb-0.76.13.dist-info}/RECORD +17 -17
- {lamindb-0.76.12.dist-info → lamindb-0.76.13.dist-info}/LICENSE +0 -0
- {lamindb-0.76.12.dist-info → lamindb-0.76.13.dist-info}/WHEEL +0 -0
lamindb/__init__.py
CHANGED
lamindb/_artifact.py
CHANGED
@@ -331,9 +331,10 @@ def get_artifact_kwargs_from_data(
|
|
331
331
|
artifact = stat_or_artifact
|
332
332
|
# update the run of the existing artifact
|
333
333
|
if run is not None:
|
334
|
-
# save the information that this artifact was previously
|
335
|
-
#
|
336
|
-
|
334
|
+
# save the information that this artifact was previously produced by
|
335
|
+
# another run
|
336
|
+
# note: same logic exists for _output_collections_with_later_updates
|
337
|
+
if artifact.run is not None and artifact.run != run:
|
337
338
|
artifact.run._output_artifacts_with_later_updates.add(artifact)
|
338
339
|
# update the run of the artifact with the latest run
|
339
340
|
stat_or_artifact.run = run
|
lamindb/_collection.py
CHANGED
@@ -145,15 +145,16 @@ def __init__(
|
|
145
145
|
logger.warning(
|
146
146
|
f"returning existing collection with same hash: {existing_collection}"
|
147
147
|
)
|
148
|
-
# update the run of the existing
|
148
|
+
# update the run of the existing collection
|
149
149
|
if run is not None:
|
150
|
-
# save the information that this
|
151
|
-
#
|
152
|
-
|
150
|
+
# save the information that this collection was previously produced
|
151
|
+
# by another run
|
152
|
+
# note: same logic exists for _output_artifacts_with_later_updates
|
153
|
+
if existing_collection.run is not None and existing_collection.run != run:
|
153
154
|
existing_collection.run._output_collections_with_later_updates.add(
|
154
155
|
existing_collection
|
155
156
|
)
|
156
|
-
# update the run of the
|
157
|
+
# update the run of the collection with the latest run
|
157
158
|
existing_collection.run = run
|
158
159
|
existing_collection.transform = run.transform
|
159
160
|
init_self_from_db(collection, existing_collection)
|
lamindb/_feature_set.py
CHANGED
@@ -216,7 +216,9 @@ def members(self) -> QuerySet:
|
|
216
216
|
|
217
217
|
|
218
218
|
def _get_related_name(self: FeatureSet) -> str:
|
219
|
-
feature_sets_related_models = dict_related_model_to_related_name(
|
219
|
+
feature_sets_related_models = dict_related_model_to_related_name(
|
220
|
+
self, instance=self._state.db
|
221
|
+
)
|
220
222
|
related_name = feature_sets_related_models.get(self.registry)
|
221
223
|
return related_name
|
222
224
|
|
lamindb/_parents.py
CHANGED
@@ -310,7 +310,12 @@ def _record_label(record: Record, field: str | None = None):
|
|
310
310
|
rf' FACE="Monospace">uid={record.uid}<BR/>version={record.version}</FONT>>'
|
311
311
|
)
|
312
312
|
elif isinstance(record, Run):
|
313
|
-
|
313
|
+
if record.transform.name:
|
314
|
+
name = f'{record.transform.name.replace("&", "&")}'
|
315
|
+
elif record.transform.key:
|
316
|
+
name = f'{record.transform.key.replace("&", "&")}'
|
317
|
+
else:
|
318
|
+
name = f"{record.transform.uid}"
|
314
319
|
user_display = (
|
315
320
|
record.created_by.handle
|
316
321
|
if record.created_by.name is None
|
@@ -365,7 +370,6 @@ def _get_all_parent_runs(data: Artifact | Collection) -> list:
|
|
365
370
|
inputs_run += (
|
366
371
|
r.input_collections.all().filter(visibility__in=[0, 1]).list()
|
367
372
|
)
|
368
|
-
run_inputs_outputs += [(inputs_run, r)]
|
369
373
|
outputs_run = (
|
370
374
|
r.__getattribute__(f"output_{name}s")
|
371
375
|
.all()
|
@@ -376,7 +380,18 @@ def _get_all_parent_runs(data: Artifact | Collection) -> list:
|
|
376
380
|
outputs_run += (
|
377
381
|
r.output_collections.all().filter(visibility__in=[0, 1]).list()
|
378
382
|
)
|
379
|
-
|
383
|
+
# if inputs are outputs artifacts are the same, will result infinite loop
|
384
|
+
# so only show as outputs
|
385
|
+
overlap = set(inputs_run).intersection(outputs_run)
|
386
|
+
if overlap:
|
387
|
+
logger.warning(
|
388
|
+
f"The following artifacts are both inputs and outputs of Run(uid={r.uid}): {overlap}\n → Only showing as outputs."
|
389
|
+
)
|
390
|
+
inputs_run = list(set(inputs_run) - overlap)
|
391
|
+
if len(inputs_run) > 0:
|
392
|
+
run_inputs_outputs += [(inputs_run, r)]
|
393
|
+
if len(outputs_run) > 0:
|
394
|
+
run_inputs_outputs += [(r, outputs_run)]
|
380
395
|
inputs += inputs_run
|
381
396
|
runs = [f.run for f in inputs if f.run is not None]
|
382
397
|
return run_inputs_outputs
|
lamindb/_query_manager.py
CHANGED
@@ -98,26 +98,11 @@ class QueryManager(models.Manager):
|
|
98
98
|
|
99
99
|
return _lookup(cls=self.all(), field=field, **kwargs)
|
100
100
|
|
101
|
-
def __getitem__(self, item: str):
|
102
|
-
try:
|
103
|
-
source_field_name = self.source_field_name
|
104
|
-
target_field_name = self.target_field_name
|
105
|
-
|
106
|
-
if (
|
107
|
-
source_field_name in {"artifact", "collection"}
|
108
|
-
and target_field_name == "feature_set"
|
109
|
-
):
|
110
|
-
return get_feature_set_by_slot_(host=self.instance).get(item)
|
111
|
-
|
112
|
-
except Exception: # pragma: no cover
|
113
|
-
return
|
114
|
-
|
115
101
|
|
116
102
|
models.Manager.list = QueryManager.list
|
117
103
|
models.Manager.df = QueryManager.df
|
118
104
|
models.Manager.search = QueryManager.search
|
119
105
|
models.Manager.lookup = QueryManager.lookup
|
120
|
-
models.Manager.__getitem__ = QueryManager.__getitem__
|
121
106
|
models.Manager._track_run_input_manager = QueryManager._track_run_input_manager
|
122
107
|
# the two lines below would be easy if we could actually inherit; like this,
|
123
108
|
# they're suboptimal
|
lamindb/_query_set.py
CHANGED
@@ -115,7 +115,7 @@ def get(
|
|
115
115
|
else:
|
116
116
|
assert idlike is None # noqa: S101
|
117
117
|
expressions = process_expressions(registry, expressions)
|
118
|
-
return registry.objects.get(**expressions)
|
118
|
+
return registry.objects.using(qs.db).get(**expressions)
|
119
119
|
|
120
120
|
|
121
121
|
class RecordsList(UserList):
|
lamindb/_record.py
CHANGED
@@ -376,6 +376,8 @@ def using(
|
|
376
376
|
instance: str | None,
|
377
377
|
) -> QuerySet:
|
378
378
|
"""{}""" # noqa: D415
|
379
|
+
from ._query_set import QuerySet
|
380
|
+
|
379
381
|
if instance is None:
|
380
382
|
return QuerySet(model=cls, using=None)
|
381
383
|
owner, name = get_owner_name_from_identifier(instance)
|
@@ -395,15 +397,15 @@ def using(
|
|
395
397
|
if not source_schema.issubset(target_schema):
|
396
398
|
missing_members = source_schema - target_schema
|
397
399
|
logger.warning(
|
398
|
-
f"source schema has additional modules: {missing_members}\nconsider mounting these schema modules to
|
400
|
+
f"source schema has additional modules: {missing_members}\nconsider mounting these schema modules to transfer all metadata"
|
399
401
|
)
|
400
|
-
cache_filepath.write_text(iresult[
|
402
|
+
cache_filepath.write_text(f"{iresult['lnid']}\n{iresult['schema_str']}") # type: ignore
|
401
403
|
settings_file = instance_settings_file(name, owner)
|
402
404
|
db = update_db_using_local(iresult, settings_file)
|
403
405
|
else:
|
404
406
|
isettings = load_instance_settings(settings_file)
|
405
407
|
db = isettings.db
|
406
|
-
cache_filepath.write_text(isettings.uid)
|
408
|
+
cache_filepath.write_text(f"{isettings.uid}\n{','.join(isettings.schema)}") # type: ignore
|
407
409
|
add_db_connection(db, instance)
|
408
410
|
return QuerySet(model=cls, using=instance)
|
409
411
|
|
@@ -470,7 +472,7 @@ def get_transfer_run(record) -> Run:
|
|
470
472
|
cache_filepath = ln_setup.settings.cache_dir / f"instance--{owner}--{name}--uid.txt"
|
471
473
|
if not cache_filepath.exists():
|
472
474
|
raise SystemExit("Need to call .using() before")
|
473
|
-
instance_uid = cache_filepath.read_text()
|
475
|
+
instance_uid = cache_filepath.read_text().split("\n")[0]
|
474
476
|
key = f"transfers/{instance_uid}"
|
475
477
|
uid = instance_uid + "0000"
|
476
478
|
transform = Transform.filter(uid=uid).one_or_none()
|
lamindb/core/_context.py
CHANGED
@@ -438,7 +438,7 @@ class Context:
|
|
438
438
|
)
|
439
439
|
return (
|
440
440
|
f'Filename "{key}" clashes with the existing key "{transform.key}" for uid "{transform.uid[:-4]}...."\n\nEither init a new transform with a new uid:\n\n'
|
441
|
-
f'ln.track("{ids.base62_12()}0000)
|
441
|
+
f'ln.track("{ids.base62_12()}0000")\n\n{update_key_note}'
|
442
442
|
)
|
443
443
|
|
444
444
|
# make a new transform record
|
lamindb/core/_django.py
CHANGED
@@ -6,7 +6,7 @@ from django.db.models.fields.reverse_related import ManyToManyRel, ManyToOneRel
|
|
6
6
|
from django.db.models.functions import JSONObject
|
7
7
|
from lnschema_core.models import Artifact, FeatureSet, Record
|
8
8
|
|
9
|
-
from .schema import dict_related_model_to_related_name
|
9
|
+
from .schema import dict_related_model_to_related_name, get_schemas_modules
|
10
10
|
|
11
11
|
|
12
12
|
def get_related_model(model, field_name):
|
@@ -35,22 +35,36 @@ def get_artifact_with_related(
|
|
35
35
|
"""Fetch an artifact with its related data."""
|
36
36
|
from lamindb._can_validate import get_name_field
|
37
37
|
|
38
|
+
from ._label_manager import LABELS_EXCLUDE_SET
|
39
|
+
|
38
40
|
model = artifact.__class__
|
39
|
-
|
41
|
+
schema_modules = get_schemas_modules(artifact._state.db)
|
42
|
+
|
43
|
+
foreign_key_fields = [
|
44
|
+
f.name
|
45
|
+
for f in model._meta.fields
|
46
|
+
if f.is_relation and f.related_model.__get_schema_name__() in schema_modules
|
47
|
+
]
|
40
48
|
|
41
49
|
m2m_relations = (
|
42
50
|
[]
|
43
51
|
if not include_m2m
|
44
52
|
else [
|
45
53
|
v
|
46
|
-
for v in dict_related_model_to_related_name(
|
47
|
-
|
54
|
+
for v in dict_related_model_to_related_name(
|
55
|
+
model, instance=artifact._state.db
|
56
|
+
).values()
|
57
|
+
if not v.startswith("_") and v not in LABELS_EXCLUDE_SET
|
48
58
|
]
|
49
59
|
)
|
50
60
|
link_tables = (
|
51
61
|
[]
|
52
62
|
if not include_feature_link
|
53
|
-
else list(
|
63
|
+
else list(
|
64
|
+
dict_related_model_to_related_name(
|
65
|
+
model, links=True, instance=artifact._state.db
|
66
|
+
).values()
|
67
|
+
)
|
54
68
|
)
|
55
69
|
|
56
70
|
# Clear previous queries
|
lamindb/core/_feature_manager.py
CHANGED
@@ -216,9 +216,11 @@ def _print_categoricals(
|
|
216
216
|
if not print_params:
|
217
217
|
labels_msg = ""
|
218
218
|
labels_by_feature = defaultdict(list)
|
219
|
-
for _, (_, links) in get_labels_as_dict(
|
219
|
+
for _, (_, links) in get_labels_as_dict(
|
220
|
+
self, links=True, instance=self._state.db
|
221
|
+
).items():
|
220
222
|
for link in links:
|
221
|
-
if link.feature_id is not None:
|
223
|
+
if hasattr(link, "feature_id") and link.feature_id is not None:
|
222
224
|
link_attr = get_link_attr(link, self)
|
223
225
|
labels_by_feature[link.feature_id].append(
|
224
226
|
getattr(link, link_attr).name
|
lamindb/core/_label_manager.py
CHANGED
@@ -26,32 +26,19 @@ if TYPE_CHECKING:
|
|
26
26
|
|
27
27
|
from lamindb._query_set import QuerySet
|
28
28
|
|
29
|
+
LABELS_EXCLUDE_SET = {"feature_sets"}
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
"input_of_runs",
|
35
|
-
"collections",
|
36
|
-
"_source_code_artifact_of",
|
37
|
-
"_report_of",
|
38
|
-
"_environment_of",
|
39
|
-
"links_collection",
|
40
|
-
"links_artifact",
|
41
|
-
"links_feature_set",
|
42
|
-
"previous_runs",
|
43
|
-
"_feature_values",
|
44
|
-
"_action_targets",
|
45
|
-
"_lnschema_core_collection__actions_+", # something seems off with this one
|
46
|
-
"_actions",
|
47
|
-
}
|
31
|
+
|
32
|
+
def get_labels_as_dict(
|
33
|
+
self: Artifact | Collection, links: bool = False, instance: str | None = None
|
34
|
+
) -> dict:
|
48
35
|
labels = {} # type: ignore
|
49
36
|
if self.id is None:
|
50
37
|
return labels
|
51
38
|
for related_model_name, related_name in dict_related_model_to_related_name(
|
52
|
-
self.__class__, links=links
|
39
|
+
self.__class__, links=links, instance=instance
|
53
40
|
).items():
|
54
|
-
if related_name not in
|
41
|
+
if related_name not in LABELS_EXCLUDE_SET and not related_name.startswith("_"):
|
55
42
|
labels[related_name] = (
|
56
43
|
related_model_name,
|
57
44
|
getattr(self, related_name).all(),
|
@@ -86,18 +73,15 @@ def print_labels(
|
|
86
73
|
labels_msg = _print_labels_postgres(self, m2m_data, print_types)
|
87
74
|
else:
|
88
75
|
labels_msg = ""
|
89
|
-
for related_name, (related_model, labels) in get_labels_as_dict(
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
labels_msg += f" .{related_name}{type_str} = {print_values}\n"
|
99
|
-
except Exception: # noqa: S112
|
100
|
-
continue
|
76
|
+
for related_name, (related_model, labels) in get_labels_as_dict(
|
77
|
+
self, instance=self._state.db
|
78
|
+
).items():
|
79
|
+
field = get_name_field(labels)
|
80
|
+
labels_list = list(labels.values_list(field, flat=True))
|
81
|
+
if len(labels_list) > 0:
|
82
|
+
print_values = _print_values(labels_list, n=10)
|
83
|
+
type_str = f": {related_model}" if print_types else ""
|
84
|
+
labels_msg += f" .{related_name}{type_str} = {print_values}\n"
|
101
85
|
|
102
86
|
msg = ""
|
103
87
|
if labels_msg:
|
@@ -214,75 +198,68 @@ class LabelManager:
|
|
214
198
|
>>> artifact1.ulabels.set(labels)
|
215
199
|
>>> artifact2.labels.add_from(artifact1)
|
216
200
|
"""
|
217
|
-
from django.db.utils import ProgrammingError
|
218
|
-
|
219
201
|
if transfer_logs is None:
|
220
202
|
transfer_logs = {"mapped": [], "transferred": [], "run": None}
|
221
203
|
using_key = settings._using_key
|
222
|
-
for related_name, (_, labels) in get_labels_as_dict(
|
204
|
+
for related_name, (_, labels) in get_labels_as_dict(
|
205
|
+
data, instance=self._host._state.db
|
206
|
+
).items():
|
223
207
|
labels = labels.all()
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
208
|
+
if not labels.exists():
|
209
|
+
continue
|
210
|
+
# look for features
|
211
|
+
data_name_lower = data.__class__.__name__.lower()
|
212
|
+
labels_by_features = defaultdict(list)
|
213
|
+
features = set()
|
214
|
+
_, new_labels = validate_labels(labels)
|
215
|
+
if len(new_labels) > 0:
|
216
|
+
transfer_fk_to_default_db_bulk(
|
217
|
+
new_labels, using_key, transfer_logs=transfer_logs
|
218
|
+
)
|
219
|
+
for label in labels:
|
220
|
+
# if the link table doesn't follow this convention, we'll ignore it
|
221
|
+
if not hasattr(label, f"links_{data_name_lower}"):
|
222
|
+
key = None
|
223
|
+
else:
|
224
|
+
link = getattr(label, f"links_{data_name_lower}").get(
|
225
|
+
**{f"{data_name_lower}_id": data.id}
|
235
226
|
)
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
key = None
|
227
|
+
if link.feature is not None:
|
228
|
+
features.add(link.feature)
|
229
|
+
key = link.feature.name
|
240
230
|
else:
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
231
|
+
key = None
|
232
|
+
label_returned = transfer_to_default_db(
|
233
|
+
label,
|
234
|
+
using_key,
|
235
|
+
transfer_logs=transfer_logs,
|
236
|
+
transfer_fk=False,
|
237
|
+
save=True,
|
238
|
+
)
|
239
|
+
# TODO: refactor return value of transfer to default db
|
240
|
+
if label_returned is not None:
|
241
|
+
label = label_returned
|
242
|
+
labels_by_features[key].append(label)
|
243
|
+
# treat features
|
244
|
+
_, new_features = validate_labels(list(features))
|
245
|
+
if len(new_features) > 0:
|
246
|
+
transfer_fk_to_default_db_bulk(
|
247
|
+
new_features, using_key, transfer_logs=transfer_logs
|
248
|
+
)
|
249
|
+
for feature in new_features:
|
250
|
+
transfer_to_default_db(
|
251
|
+
feature,
|
251
252
|
using_key,
|
252
253
|
transfer_logs=transfer_logs,
|
253
254
|
transfer_fk=False,
|
254
|
-
save=True,
|
255
255
|
)
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
256
|
+
save(new_features)
|
257
|
+
if hasattr(self._host, related_name):
|
258
|
+
for feature_name, labels in labels_by_features.items():
|
259
|
+
if feature_name is not None:
|
260
|
+
feature_id = Feature.get(name=feature_name).id
|
261
|
+
else:
|
262
|
+
feature_id = None
|
263
|
+
getattr(self._host, related_name).add(
|
264
|
+
*labels, through_defaults={"feature_id": feature_id}
|
265
265
|
)
|
266
|
-
for feature in new_features:
|
267
|
-
transfer_to_default_db(
|
268
|
-
feature,
|
269
|
-
using_key,
|
270
|
-
transfer_logs=transfer_logs,
|
271
|
-
transfer_fk=False,
|
272
|
-
)
|
273
|
-
save(new_features)
|
274
|
-
if hasattr(self._host, related_name):
|
275
|
-
for feature_name, labels in labels_by_features.items():
|
276
|
-
if feature_name is not None:
|
277
|
-
feature_id = Feature.get(name=feature_name).id
|
278
|
-
else:
|
279
|
-
feature_id = None
|
280
|
-
getattr(self._host, related_name).add(
|
281
|
-
*labels, through_defaults={"feature_id": feature_id}
|
282
|
-
)
|
283
|
-
# ProgrammingError is raised when schemas don't match between source and target instances
|
284
|
-
except ProgrammingError:
|
285
|
-
logger.warning(
|
286
|
-
f"{related_name} labels cannot be transferred because schema module does not exist in target instance: {labels}"
|
287
|
-
)
|
288
|
-
continue
|
lamindb/core/schema.py
CHANGED
@@ -1,31 +1,66 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
+
import lamindb_setup as ln_setup
|
3
4
|
from django.db.models import ManyToManyField
|
5
|
+
from lamindb_setup._connect_instance import (
|
6
|
+
get_owner_name_from_identifier,
|
7
|
+
load_instance_settings,
|
8
|
+
)
|
9
|
+
from lamindb_setup.core._settings_store import instance_settings_file
|
4
10
|
from lnschema_core.models import Feature, FeatureSet, LinkORM, Record
|
5
11
|
|
6
12
|
|
7
|
-
def
|
13
|
+
def get_schemas_modules(instance: str | None) -> set[str]:
|
14
|
+
if instance is None or instance == "default":
|
15
|
+
schema_modules = set(ln_setup.settings.instance.schema)
|
16
|
+
schema_modules.add("core")
|
17
|
+
return schema_modules
|
18
|
+
owner, name = get_owner_name_from_identifier(instance)
|
19
|
+
settings_file = instance_settings_file(name, owner)
|
20
|
+
if settings_file.exists():
|
21
|
+
schema = set(load_instance_settings(settings_file).schema)
|
22
|
+
else:
|
23
|
+
cache_filepath = (
|
24
|
+
ln_setup.settings.cache_dir / f"instance--{owner}--{name}--uid.txt"
|
25
|
+
)
|
26
|
+
if cache_filepath.exists():
|
27
|
+
schema = set(cache_filepath.read_text().split("\n")[1].split(","))
|
28
|
+
else:
|
29
|
+
raise ValueError(f"Instance {instance} not found")
|
30
|
+
shared_schema_modules = set(ln_setup.settings.instance.schema).intersection(schema)
|
31
|
+
shared_schema_modules.add("core")
|
32
|
+
return shared_schema_modules
|
33
|
+
|
34
|
+
|
35
|
+
def dict_schema_name_to_model_name(
|
36
|
+
registry: type[Record], instance: str | None = None
|
37
|
+
) -> dict[str, Record]:
|
38
|
+
schema_modules = get_schemas_modules(instance)
|
8
39
|
d: dict = {
|
9
40
|
i.related_model.__get_name_with_schema__(): i.related_model
|
10
41
|
for i in registry._meta.related_objects
|
11
42
|
if i.related_name is not None
|
43
|
+
and i.related_model.__get_schema_name__() in schema_modules
|
12
44
|
}
|
13
45
|
d.update(
|
14
46
|
{
|
15
47
|
i.related_model.__get_name_with_schema__(): i.related_model
|
16
48
|
for i in registry._meta.many_to_many
|
17
49
|
if i.name is not None
|
50
|
+
and i.related_model.__get_schema_name__() in schema_modules
|
18
51
|
}
|
19
52
|
)
|
20
53
|
return d
|
21
54
|
|
22
55
|
|
23
56
|
def dict_related_model_to_related_name(
|
24
|
-
registry: type[Record], links: bool = False
|
57
|
+
registry: type[Record], links: bool = False, instance: str | None = None
|
25
58
|
) -> dict[str, str]:
|
26
59
|
def include(model: Record):
|
27
60
|
return not links != issubclass(model, LinkORM)
|
28
61
|
|
62
|
+
schema_modules = get_schemas_modules(instance)
|
63
|
+
|
29
64
|
related_objects = registry._meta.related_objects + registry._meta.many_to_many
|
30
65
|
d: dict = {
|
31
66
|
record.related_model.__get_name_with_schema__(): (
|
@@ -34,7 +69,11 @@ def dict_related_model_to_related_name(
|
|
34
69
|
else record.name
|
35
70
|
)
|
36
71
|
for record in related_objects
|
37
|
-
if (
|
72
|
+
if (
|
73
|
+
record.name is not None
|
74
|
+
and include(record.related_model)
|
75
|
+
and record.related_model.__get_schema_name__() in schema_modules
|
76
|
+
)
|
38
77
|
}
|
39
78
|
return d
|
40
79
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: lamindb
|
3
|
-
Version: 0.76.
|
3
|
+
Version: 0.76.13
|
4
4
|
Summary: A data framework for biology.
|
5
5
|
Author-email: Lamin Labs <open-source@lamin.ai>
|
6
6
|
Requires-Python: >=3.9
|
@@ -10,7 +10,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.11
|
11
11
|
Requires-Dist: lnschema_core==0.75.0
|
12
12
|
Requires-Dist: lamin_utils==0.13.6
|
13
|
-
Requires-Dist: lamin_cli==0.
|
13
|
+
Requires-Dist: lamin_cli==0.19.0
|
14
14
|
Requires-Dist: lamindb_setup
|
15
15
|
Requires-Dist: rapidfuzz
|
16
16
|
Requires-Dist: pyarrow
|
@@ -1,18 +1,18 @@
|
|
1
|
-
lamindb/__init__.py,sha256=
|
2
|
-
lamindb/_artifact.py,sha256=
|
1
|
+
lamindb/__init__.py,sha256=h_byT1s_9NrqH157lvPgG336CTBqGzIIJNlNU7MKWQE,2278
|
2
|
+
lamindb/_artifact.py,sha256=AHyKZ_D_qMGtywAklo42je8BZB-VBqQ-ZTaI9AB_Yxs,44905
|
3
3
|
lamindb/_can_validate.py,sha256=1pUavLwZ_yPAtbVYKOGYUHaPxlJGZ246qZ0e-4ZUDSc,19552
|
4
|
-
lamindb/_collection.py,sha256=
|
4
|
+
lamindb/_collection.py,sha256=ZQ45_9n0komz1y8l_vzZ-cRn-ghinE0Izl889Mk-TSA,14249
|
5
5
|
lamindb/_curate.py,sha256=KpEP0-9nQUmiRn6z7fiGs6BmQdpqSg3QPlAgV-S9_wA,58839
|
6
6
|
lamindb/_feature.py,sha256=nZhtrH0ssoNls-hV-dkwfK9sKypg2El59R9qfarxfUE,5340
|
7
|
-
lamindb/_feature_set.py,sha256=
|
7
|
+
lamindb/_feature_set.py,sha256=JQSP-YLam1KW-rDzly5Dm4IYVL2A6ec7ufIf6iCc2W8,8169
|
8
8
|
lamindb/_filter.py,sha256=Pf9NHV4gm7NOC0Frtvx4W7nvwt2EowOP74DwppyXAZs,635
|
9
9
|
lamindb/_finish.py,sha256=VMAmxCUFmTKIMSCx7LEh4QAnWDeue6MeUAAzkMVEYMU,9546
|
10
10
|
lamindb/_from_values.py,sha256=iqcR8T8i9VZpnn09W441zW-djhWMh8EZj7XFJq9jP2k,14211
|
11
11
|
lamindb/_is_versioned.py,sha256=5lAnhTboltFkZCKVRV1uxkm0OCjJz_HKi3yQq_vEuMs,1306
|
12
|
-
lamindb/_parents.py,sha256=
|
13
|
-
lamindb/_query_manager.py,sha256=
|
14
|
-
lamindb/_query_set.py,sha256=
|
15
|
-
lamindb/_record.py,sha256=
|
12
|
+
lamindb/_parents.py,sha256=KMBUfCLNqjmFzOdZIXaUFqDPeEpWP28MCkHHPq887h8,16341
|
13
|
+
lamindb/_query_manager.py,sha256=pmPhJQ85-7XeAU9TFv6LPGi9F7dBgztZgZcXz33HYJM,3710
|
14
|
+
lamindb/_query_set.py,sha256=81y1c-Y-PGCmqc64WizlCiGTbsrApsajtX2xj7xrsMo,12730
|
15
|
+
lamindb/_record.py,sha256=LkKtDxqlTq43UlAiJ96_nbpjj9eQbU4N3HpfBVfImJo,23395
|
16
16
|
lamindb/_run.py,sha256=K_5drpLn3D7y3XtZ3vtAw35rG5RCSvB4bXQZx4ESSI0,1964
|
17
17
|
lamindb/_save.py,sha256=BCaSFnANYPxTqL5gw7Hrh_9kz7SDyOxrJV2KW6rXqts,11366
|
18
18
|
lamindb/_storage.py,sha256=GBVChv-DHVMNEBJL5l_JT6B4RDhZ6NnwgzmUICphYKk,413
|
@@ -21,11 +21,11 @@ lamindb/_ulabel.py,sha256=XDSdZBXX_ki5s1vOths3MjF2x5DPggBR_PV_KF4SGyg,1611
|
|
21
21
|
lamindb/_utils.py,sha256=LGdiW4k3GClLz65vKAVRkL6Tw-Gkx9DWAdez1jyA5bE,428
|
22
22
|
lamindb/_view.py,sha256=4Ln2ItTb3857PAI-70O8eJYqoTJ_NNFc7E_wds6OGns,2412
|
23
23
|
lamindb/core/__init__.py,sha256=57AXQ286eOX2_o5HUeqIFJrfqN-OZ_E7FVHd3Xm5oOk,1483
|
24
|
-
lamindb/core/_context.py,sha256=
|
24
|
+
lamindb/core/_context.py,sha256=dI3z7fCMRPC3IMb7-EIaQYhacSZBA4HfLVFyoJtVL7I,22900
|
25
25
|
lamindb/core/_data.py,sha256=P0vlbw_UQp9UDNMmUo9YFxqurcWtMaKPWCT12IRA2C0,19672
|
26
|
-
lamindb/core/_django.py,sha256=
|
27
|
-
lamindb/core/_feature_manager.py,sha256=
|
28
|
-
lamindb/core/_label_manager.py,sha256=
|
26
|
+
lamindb/core/_django.py,sha256=yeMPp1n9WrFmEjVRdavfpVqAolPLd24RseTQlvsK67w,7157
|
27
|
+
lamindb/core/_feature_manager.py,sha256=yH6HGF_c0NwIE6hxcMUZdZrokx75Kz-54d_3JhyCglQ,39020
|
28
|
+
lamindb/core/_label_manager.py,sha256=bhD6krOrf0SWXfCzhFsEA-7h0ZLJ59YSPxWnlq7DZiE,9991
|
29
29
|
lamindb/core/_mapped_collection.py,sha256=M50haewVAFONeF71QQbzD09L8lVZCL1hyf0W87jKE5U,24575
|
30
30
|
lamindb/core/_settings.py,sha256=6jNadlQdimxCsKR2ZyUD0YJYzOdubTnKktki-MqEWqQ,6137
|
31
31
|
lamindb/core/_sync_git.py,sha256=lIgl6YfpH4rCFT1WILAp7zlemZfxog1d0zp3cX0KIZw,4531
|
@@ -33,7 +33,7 @@ lamindb/core/_track_environment.py,sha256=Ywzg_sJ7guI1dcsN7h5orce9VdYl8VGVE3OLIT
|
|
33
33
|
lamindb/core/exceptions.py,sha256=0B36kOVo-Dik5KbSKvy5GPuMjUfhVb99dJwXl_J0ldo,1636
|
34
34
|
lamindb/core/fields.py,sha256=47Jmh3efUr5ZscgimR_yckY-I3cNf8ScLutbwKCK3j4,162
|
35
35
|
lamindb/core/loaders.py,sha256=KMTkDa73jkRVvI9uc5Fgr0t6mq22cAxBwhSlUZKUaBg,4016
|
36
|
-
lamindb/core/schema.py,sha256=
|
36
|
+
lamindb/core/schema.py,sha256=Y1tGn93B236PtnYZkpgTNFgTXBcVujPM1qh1kNG6Nbs,3441
|
37
37
|
lamindb/core/types.py,sha256=uVBqSVLoQaTkqP9nqsJhwU6yYnx8H5e6-ZxrB6vpOOw,265
|
38
38
|
lamindb/core/versioning.py,sha256=KUpd94F5QpbDxx9eKgZwrpPyQpm9YeHVedrTEO2a_mI,4839
|
39
39
|
lamindb/core/datasets/__init__.py,sha256=zRP98oqUAaXhqWyKMiH0s_ImVIuNeziQQ2kQ_t0f-DI,1353
|
@@ -55,7 +55,7 @@ lamindb/integrations/__init__.py,sha256=RWGMYYIzr8zvmNPyVB4m-p4gMDhxdRbjES2Ed23O
|
|
55
55
|
lamindb/integrations/_vitessce.py,sha256=uPl45_w4Uu9_BhpBDDVonC1nDOuAnB7DAnzi5w5bZAE,4032
|
56
56
|
lamindb/setup/__init__.py,sha256=OwZpZzPDv5lPPGXZP7-zK6UdO4FHvvuBh439yZvIp3A,410
|
57
57
|
lamindb/setup/core/__init__.py,sha256=SevlVrc2AZWL3uALbE5sopxBnIZPWZ1IB0NBDudiAL8,167
|
58
|
-
lamindb-0.76.
|
59
|
-
lamindb-0.76.
|
60
|
-
lamindb-0.76.
|
61
|
-
lamindb-0.76.
|
58
|
+
lamindb-0.76.13.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
59
|
+
lamindb-0.76.13.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
|
60
|
+
lamindb-0.76.13.dist-info/METADATA,sha256=Vo8AcZfSEBwW3NJsFndztG1b2fAVSquWw2OENmncc8M,2361
|
61
|
+
lamindb-0.76.13.dist-info/RECORD,,
|
File without changes
|
File without changes
|