lamindb_setup 0.70.0__py2.py3-none-any.whl → 0.71.0__py2.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_setup/__init__.py +15 -15
- lamindb_setup/_add_remote_storage.py +22 -33
- lamindb_setup/_cache.py +4 -1
- lamindb_setup/_check.py +3 -0
- lamindb_setup/_check_setup.py +13 -7
- lamindb_setup/_close.py +2 -0
- lamindb_setup/_connect_instance.py +33 -26
- lamindb_setup/_delete.py +52 -19
- lamindb_setup/_django.py +4 -1
- lamindb_setup/_exportdb.py +4 -2
- lamindb_setup/_importdb.py +5 -1
- lamindb_setup/_init_instance.py +57 -45
- lamindb_setup/_migrate.py +16 -13
- lamindb_setup/_register_instance.py +10 -3
- lamindb_setup/_schema.py +6 -3
- lamindb_setup/_setup_user.py +7 -7
- lamindb_setup/_silence_loggers.py +4 -2
- lamindb_setup/core/__init__.py +4 -3
- lamindb_setup/core/_aws_storage.py +3 -0
- lamindb_setup/core/_deprecated.py +2 -7
- lamindb_setup/core/_docs.py +2 -0
- lamindb_setup/core/_hub_client.py +12 -10
- lamindb_setup/core/_hub_core.py +198 -88
- lamindb_setup/core/_hub_crud.py +15 -11
- lamindb_setup/core/_hub_utils.py +11 -8
- lamindb_setup/core/_settings.py +23 -26
- lamindb_setup/core/_settings_instance.py +149 -81
- lamindb_setup/core/_settings_load.py +12 -7
- lamindb_setup/core/_settings_save.py +11 -8
- lamindb_setup/core/_settings_storage.py +83 -42
- lamindb_setup/core/_settings_store.py +3 -2
- lamindb_setup/core/_settings_user.py +10 -6
- lamindb_setup/core/_setup_bionty_sources.py +9 -2
- lamindb_setup/core/cloud_sqlite_locker.py +13 -10
- lamindb_setup/core/django.py +3 -1
- lamindb_setup/core/exceptions.py +4 -2
- lamindb_setup/core/hashing.py +15 -5
- lamindb_setup/core/types.py +5 -2
- lamindb_setup/core/upath.py +181 -87
- {lamindb_setup-0.70.0.dist-info → lamindb_setup-0.71.0.dist-info}/METADATA +6 -4
- lamindb_setup-0.71.0.dist-info/RECORD +43 -0
- lamindb_setup-0.70.0.dist-info/RECORD +0 -43
- {lamindb_setup-0.70.0.dist-info → lamindb_setup-0.71.0.dist-info}/LICENSE +0 -0
- {lamindb_setup-0.70.0.dist-info → lamindb_setup-0.71.0.dist-info}/WHEEL +0 -0
lamindb_setup/__init__.py
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
"""Setup & configure LaminDB.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Typically, you'll want to use the CLI rather than this API.
|
|
3
|
+
Many functions in this "setup API" have a matching command in the :doc:`docs:cli` CLI.
|
|
6
4
|
|
|
7
5
|
Guide: :doc:`docs:setup`.
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
Basic operations:
|
|
10
8
|
|
|
11
9
|
.. autosummary::
|
|
12
10
|
:toctree:
|
|
@@ -17,7 +15,7 @@ Setup:
|
|
|
17
15
|
close
|
|
18
16
|
delete
|
|
19
17
|
|
|
20
|
-
|
|
18
|
+
Instance operations:
|
|
21
19
|
|
|
22
20
|
.. autosummary::
|
|
23
21
|
:toctree:
|
|
@@ -36,22 +34,22 @@ Modules & settings:
|
|
|
36
34
|
|
|
37
35
|
"""
|
|
38
36
|
|
|
39
|
-
__version__ = "0.
|
|
37
|
+
__version__ = "0.71.0" # denote a release candidate for 0.1.0 with 0.1rc1
|
|
40
38
|
|
|
41
39
|
import sys
|
|
42
40
|
from os import name as _os_name
|
|
43
41
|
|
|
44
42
|
from . import core
|
|
45
|
-
from ._close import close # noqa
|
|
46
|
-
from ._delete import delete # noqa
|
|
47
|
-
from ._init_instance import init # noqa
|
|
48
|
-
from ._connect_instance import connect, load # noqa
|
|
49
|
-
from ._migrate import migrate
|
|
50
|
-
from ._register_instance import register # noqa
|
|
51
|
-
from .core._settings import settings # noqa
|
|
52
|
-
from ._setup_user import login, logout # noqa
|
|
53
|
-
from ._django import django
|
|
54
43
|
from ._check_setup import _check_instance_setup
|
|
44
|
+
from ._close import close
|
|
45
|
+
from ._connect_instance import connect, load
|
|
46
|
+
from ._delete import delete
|
|
47
|
+
from ._django import django
|
|
48
|
+
from ._init_instance import init
|
|
49
|
+
from ._migrate import migrate
|
|
50
|
+
from ._register_instance import register
|
|
51
|
+
from ._setup_user import login, logout
|
|
52
|
+
from .core._settings import settings
|
|
55
53
|
|
|
56
54
|
dev = core # backward compat
|
|
57
55
|
_TESTING = False # used in lamindb tests
|
|
@@ -70,3 +68,5 @@ if _os_name == "nt":
|
|
|
70
68
|
_original_excepthook(args)
|
|
71
69
|
|
|
72
70
|
threading.excepthook = _except_hook
|
|
71
|
+
|
|
72
|
+
settings.__doc__ = """Global :class:`~lamindb.setup.core.SetupSettings`."""
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
from
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
2
4
|
|
|
3
|
-
from
|
|
5
|
+
from lamin_utils import logger
|
|
4
6
|
|
|
5
|
-
from ._init_instance import
|
|
7
|
+
from ._init_instance import register_storage_in_instance
|
|
6
8
|
from .core._settings import settings
|
|
7
|
-
from .core.
|
|
8
|
-
|
|
9
|
+
from .core._settings_storage import init_storage
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from lamindb_setup.core.types import UPathStr
|
|
9
13
|
|
|
10
14
|
|
|
11
|
-
def
|
|
15
|
+
def add_managed_storage(root: UPathStr, **fs_kwargs):
|
|
12
16
|
"""Add a remote default storage location to a local instance.
|
|
13
17
|
|
|
14
18
|
This can be used to selectively share data.
|
|
@@ -17,34 +21,19 @@ def switch_default_storage(root: UPathStr, **fs_kwargs):
|
|
|
17
21
|
root: `UPathStr` - The new storage root, e.g., an S3 bucket.
|
|
18
22
|
**fs_kwargs: Additional fsspec arguments for cloud root, e.g., profile.
|
|
19
23
|
|
|
20
|
-
Example:
|
|
21
|
-
>>> ln.setup.set.storage(
|
|
22
|
-
>>> "s3://some-bucket",
|
|
23
|
-
>>> profile="some_profile", # fsspec arg
|
|
24
|
-
>>> cache_regions=True # fsspec arg for s3
|
|
25
|
-
>>> )
|
|
26
|
-
|
|
27
24
|
"""
|
|
28
25
|
if settings.instance.dialect == "sqlite":
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
id=settings.instance.id,
|
|
26
|
+
raise ValueError(
|
|
27
|
+
"Can't add additional managed storage locations for sqlite instances."
|
|
28
|
+
)
|
|
29
|
+
if not settings.instance.is_on_hub:
|
|
30
|
+
raise ValueError(
|
|
31
|
+
"Can't add additional managed storage locations for instances that aren't managed through the hub."
|
|
32
|
+
)
|
|
33
|
+
ssettings = init_storage(
|
|
34
|
+
root=root, instance_id=settings.instance._id, register_hub=True
|
|
39
35
|
)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
# we are not doing this for now because of difficulties to define the right RLS policy # noqa
|
|
44
|
-
# https://laminlabs.slack.com/archives/C04FPE8V01W/p1687948324601929?thread_ts=1687531921.394119&cid=C04FPE8V01W
|
|
45
|
-
# if settings.instance.is_remote:
|
|
46
|
-
# init_storage_hub(
|
|
47
|
-
# root, account_handle=settings.instance.owner # type: ignore
|
|
48
|
-
# )
|
|
49
|
-
|
|
36
|
+
settings.instance._storage = ssettings
|
|
37
|
+
settings.instance._persist() # this also updates the settings object
|
|
38
|
+
register_storage_in_instance(ssettings)
|
|
50
39
|
settings.storage._set_fs_kwargs(**fs_kwargs)
|
lamindb_setup/_cache.py
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import shutil
|
|
4
|
+
|
|
2
5
|
from lamin_utils import logger
|
|
3
6
|
|
|
4
7
|
|
|
5
8
|
def clear_cache_dir():
|
|
6
|
-
from lamindb_setup import
|
|
9
|
+
from lamindb_setup import close, settings
|
|
7
10
|
|
|
8
11
|
if settings.instance._is_cloud_sqlite:
|
|
9
12
|
logger.warning(
|
lamindb_setup/_check.py
CHANGED
lamindb_setup/_check_setup.py
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
3
|
import os
|
|
4
|
+
from typing import TYPE_CHECKING, Optional
|
|
5
|
+
|
|
6
|
+
from lamin_utils import logger
|
|
7
|
+
|
|
4
8
|
from ._silence_loggers import silence_loggers
|
|
9
|
+
from .core import django
|
|
10
|
+
from .core._settings import settings
|
|
5
11
|
from .core._settings_store import current_instance_settings_file
|
|
6
12
|
from .core.exceptions import DefaultMessageException
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
from .core import
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from .core._settings_instance import InstanceSettings
|
|
10
16
|
|
|
11
17
|
|
|
12
18
|
class InstanceNotSetupError(DefaultMessageException):
|
|
@@ -19,10 +25,10 @@ If you used the CLI to set up lamindb in a notebook, restart the Python session.
|
|
|
19
25
|
"""
|
|
20
26
|
|
|
21
27
|
|
|
22
|
-
CURRENT_ISETTINGS:
|
|
28
|
+
CURRENT_ISETTINGS: InstanceSettings | None = None
|
|
23
29
|
|
|
24
30
|
|
|
25
|
-
def _get_current_instance_settings() ->
|
|
31
|
+
def _get_current_instance_settings() -> InstanceSettings | None:
|
|
26
32
|
global CURRENT_ISETTINGS
|
|
27
33
|
|
|
28
34
|
if CURRENT_ISETTINGS is not None:
|
lamindb_setup/_close.py
CHANGED
|
@@ -1,26 +1,32 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
from uuid import UUID
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
4
3
|
import os
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
from uuid import UUID
|
|
6
|
+
|
|
5
7
|
from lamin_utils import logger
|
|
6
|
-
|
|
7
|
-
from
|
|
8
|
+
|
|
9
|
+
from ._check_setup import _check_instance_setup
|
|
10
|
+
from ._close import close as close_instance
|
|
11
|
+
from ._init_instance import MESSAGE_NO_MULTIPLE_INSTANCE, load_from_isettings
|
|
12
|
+
from ._migrate import check_whether_migrations_in_sync
|
|
13
|
+
from ._silence_loggers import silence_loggers
|
|
14
|
+
from .core._hub_core import connect_instance as load_instance_from_hub
|
|
15
|
+
from .core._hub_utils import (
|
|
8
16
|
LaminDsn,
|
|
9
17
|
LaminDsnModel,
|
|
10
18
|
)
|
|
11
|
-
from .
|
|
12
|
-
from .
|
|
13
|
-
from .core._settings import InstanceSettings, settings
|
|
14
|
-
from ._silence_loggers import silence_loggers
|
|
19
|
+
from .core._settings import settings
|
|
20
|
+
from .core._settings_instance import InstanceSettings
|
|
15
21
|
from .core._settings_load import load_instance_settings
|
|
16
22
|
from .core._settings_storage import StorageSettings
|
|
17
23
|
from .core._settings_store import instance_settings_file
|
|
18
24
|
from .core.cloud_sqlite_locker import unlock_cloud_sqlite_upon_exception
|
|
19
|
-
from ._init_instance import MESSAGE_NO_MULTIPLE_INSTANCE
|
|
20
|
-
from ._check_setup import _check_instance_setup
|
|
21
|
-
from .core._hub_core import connect_instance as load_instance_from_hub
|
|
22
|
-
from ._migrate import check_whether_migrations_in_sync
|
|
23
25
|
|
|
26
|
+
if TYPE_CHECKING:
|
|
27
|
+
from pathlib import Path
|
|
28
|
+
|
|
29
|
+
from .core.types import UPathStr
|
|
24
30
|
|
|
25
31
|
# this is for testing purposes only
|
|
26
32
|
# set to True only to test failed load
|
|
@@ -48,8 +54,8 @@ def check_db_dsn_equal_up_to_credentials(db_dsn_hub, db_dsn_local):
|
|
|
48
54
|
|
|
49
55
|
|
|
50
56
|
def update_db_using_local(
|
|
51
|
-
hub_instance_result:
|
|
52
|
-
) ->
|
|
57
|
+
hub_instance_result: dict[str, str], settings_file: Path, db: str | None = None
|
|
58
|
+
) -> str | None:
|
|
53
59
|
db_updated = None
|
|
54
60
|
# check if postgres
|
|
55
61
|
if hub_instance_result["db_scheme"] == "postgresql":
|
|
@@ -98,11 +104,11 @@ def update_db_using_local(
|
|
|
98
104
|
def connect(
|
|
99
105
|
slug: str,
|
|
100
106
|
*,
|
|
101
|
-
db:
|
|
102
|
-
storage:
|
|
107
|
+
db: str | None = None,
|
|
108
|
+
storage: UPathStr | None = None,
|
|
103
109
|
_raise_not_reachable_error: bool = True,
|
|
104
110
|
_test: bool = False,
|
|
105
|
-
) ->
|
|
111
|
+
) -> str | tuple | None:
|
|
106
112
|
"""Connect to instance.
|
|
107
113
|
|
|
108
114
|
Args:
|
|
@@ -133,7 +139,7 @@ def connect(
|
|
|
133
139
|
if settings_file.exists():
|
|
134
140
|
isettings = load_instance_settings(settings_file)
|
|
135
141
|
# mimic instance_result from hub
|
|
136
|
-
instance_result = {"id": isettings.
|
|
142
|
+
instance_result = {"id": isettings._id.hex}
|
|
137
143
|
# skip hub request for a purely local instance
|
|
138
144
|
make_hub_request = isettings.is_remote
|
|
139
145
|
|
|
@@ -161,7 +167,8 @@ def connect(
|
|
|
161
167
|
db=db_updated,
|
|
162
168
|
schema=instance_result["schema_str"],
|
|
163
169
|
git_repo=instance_result["git_repo"],
|
|
164
|
-
|
|
170
|
+
keep_artifacts_local=bool(instance_result["keep_artifacts_local"]),
|
|
171
|
+
is_on_hub=True,
|
|
165
172
|
)
|
|
166
173
|
check_whether_migrations_in_sync(instance_result["lamindb_version"])
|
|
167
174
|
else:
|
|
@@ -173,12 +180,12 @@ def connect(
|
|
|
173
180
|
if isettings.is_remote:
|
|
174
181
|
if _raise_not_reachable_error:
|
|
175
182
|
raise InstanceNotFoundError(message)
|
|
176
|
-
return "instance-not-
|
|
183
|
+
return "instance-not-found"
|
|
177
184
|
|
|
178
185
|
else:
|
|
179
186
|
if _raise_not_reachable_error:
|
|
180
187
|
raise InstanceNotFoundError(message)
|
|
181
|
-
return "instance-not-
|
|
188
|
+
return "instance-not-found"
|
|
182
189
|
|
|
183
190
|
if storage is not None:
|
|
184
191
|
update_isettings_with_storage(isettings, storage)
|
|
@@ -203,7 +210,7 @@ def connect(
|
|
|
203
210
|
raise SystemExit(msg)
|
|
204
211
|
else:
|
|
205
212
|
logger.warning(
|
|
206
|
-
f"instance exists with id {isettings.
|
|
213
|
+
f"instance exists with id {isettings._id.hex}, but database is not"
|
|
207
214
|
" loadable: re-initializing"
|
|
208
215
|
)
|
|
209
216
|
return "instance-corrupted-or-deleted", instance_result
|
|
@@ -224,9 +231,9 @@ def connect(
|
|
|
224
231
|
def load(
|
|
225
232
|
slug: str,
|
|
226
233
|
*,
|
|
227
|
-
db:
|
|
228
|
-
storage:
|
|
229
|
-
) ->
|
|
234
|
+
db: str | None = None,
|
|
235
|
+
storage: UPathStr | None = None,
|
|
236
|
+
) -> str | tuple | None:
|
|
230
237
|
"""Connect to instance and set ``auto-connect`` to true.
|
|
231
238
|
|
|
232
239
|
This is exactly the same as ``ln.connect()`` except for that
|
lamindb_setup/_delete.py
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import shutil
|
|
2
|
-
from
|
|
3
|
-
from lamin_utils import logger
|
|
4
|
+
from typing import TYPE_CHECKING, Optional
|
|
4
5
|
from uuid import UUID
|
|
5
|
-
|
|
6
|
-
from
|
|
7
|
-
|
|
6
|
+
|
|
7
|
+
from lamin_utils import logger
|
|
8
|
+
|
|
9
|
+
from ._connect_instance import INSTANCE_NOT_FOUND_MESSAGE
|
|
10
|
+
from .core._hub_core import connect_instance as load_instance_from_hub
|
|
11
|
+
from .core._hub_core import delete_instance as delete_instance_on_hub
|
|
12
|
+
from .core._hub_core import get_storage_records_for_instance
|
|
8
13
|
from .core._settings import settings
|
|
14
|
+
from .core._settings_instance import InstanceSettings
|
|
9
15
|
from .core._settings_load import load_instance_settings
|
|
16
|
+
from .core._settings_storage import StorageSettings
|
|
10
17
|
from .core._settings_store import instance_settings_file
|
|
11
|
-
from .core.upath import
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
from
|
|
18
|
+
from .core.upath import HOSTED_BUCKETS, check_storage_is_empty
|
|
19
|
+
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from pathlib import Path
|
|
15
22
|
|
|
16
23
|
|
|
17
24
|
def delete_cache(cache_dir: Path):
|
|
@@ -20,7 +27,7 @@ def delete_cache(cache_dir: Path):
|
|
|
20
27
|
|
|
21
28
|
|
|
22
29
|
def delete_exclusion_dir(isettings: InstanceSettings) -> None:
|
|
23
|
-
exclusion_dir = isettings.storage.root / f".lamindb/_exclusion/{isettings.
|
|
30
|
+
exclusion_dir = isettings.storage.root / f".lamindb/_exclusion/{isettings._id.hex}"
|
|
24
31
|
if exclusion_dir.exists():
|
|
25
32
|
exclusion_dir.rmdir()
|
|
26
33
|
|
|
@@ -45,13 +52,11 @@ def delete_by_isettings(isettings: InstanceSettings) -> None:
|
|
|
45
52
|
if settings._instance_settings_path.exists():
|
|
46
53
|
settings._instance_settings_path.unlink()
|
|
47
54
|
settings._instance_settings = None
|
|
48
|
-
if isettings.storage._mark_storage_root.exists():
|
|
49
|
-
isettings.storage._mark_storage_root.unlink()
|
|
50
55
|
|
|
51
56
|
|
|
52
57
|
def delete(
|
|
53
58
|
instance_name: str, force: bool = False, require_empty: bool = True
|
|
54
|
-
) ->
|
|
59
|
+
) -> int | None:
|
|
55
60
|
"""Delete a LaminDB instance.
|
|
56
61
|
|
|
57
62
|
Args:
|
|
@@ -94,7 +99,7 @@ def delete(
|
|
|
94
99
|
owner=settings.user.handle,
|
|
95
100
|
name=instance_name,
|
|
96
101
|
storage=ssettings,
|
|
97
|
-
|
|
102
|
+
keep_artifacts_local=bool(instance_result["keep_artifacts_local"]),
|
|
98
103
|
db=instance_result["db"] if "db" in instance_result else None,
|
|
99
104
|
schema=instance_result["schema_str"],
|
|
100
105
|
git_repo=instance_result["git_repo"],
|
|
@@ -105,6 +110,10 @@ def delete(
|
|
|
105
110
|
logger.warning(
|
|
106
111
|
f"delete() does not yet affect your Postgres database at {isettings.db}"
|
|
107
112
|
)
|
|
113
|
+
if isettings.is_on_hub and settings.user.handle == "anonymous":
|
|
114
|
+
logger.warning(
|
|
115
|
+
"won't delete the hub component of this instance because you're not logged in"
|
|
116
|
+
)
|
|
108
117
|
if not force:
|
|
109
118
|
valid_responses = ["y", "yes"]
|
|
110
119
|
user_input = (
|
|
@@ -120,25 +129,49 @@ def delete(
|
|
|
120
129
|
# delete the exlusion dir first because it's hard to count its objects
|
|
121
130
|
delete_exclusion_dir(isettings)
|
|
122
131
|
if isettings.storage.type_is_cloud and isettings.storage.root_as_str.startswith(
|
|
123
|
-
|
|
132
|
+
HOSTED_BUCKETS
|
|
124
133
|
):
|
|
125
134
|
if not require_empty:
|
|
126
135
|
logger.warning(
|
|
127
136
|
"hosted storage always has to be empty, ignoring `require_empty`"
|
|
128
137
|
)
|
|
129
138
|
require_empty = True
|
|
139
|
+
# first the default storage
|
|
130
140
|
n_objects = check_storage_is_empty(
|
|
131
141
|
isettings.storage.root,
|
|
132
142
|
raise_error=require_empty,
|
|
133
143
|
account_for_sqlite_file=isettings.dialect == "sqlite",
|
|
134
144
|
)
|
|
145
|
+
if isettings.storage._mark_storage_root.exists():
|
|
146
|
+
isettings.storage._mark_storage_root.unlink(
|
|
147
|
+
missing_ok=True # this is totally weird, but needed on Py3.11
|
|
148
|
+
)
|
|
149
|
+
# now everything that's on the hub
|
|
150
|
+
if settings.user.handle != "anonymous":
|
|
151
|
+
storage_records = get_storage_records_for_instance(isettings._id)
|
|
152
|
+
for storage_record in storage_records:
|
|
153
|
+
if storage_record["root"] == isettings.storage.root_as_str:
|
|
154
|
+
continue
|
|
155
|
+
check_storage_is_empty(
|
|
156
|
+
storage_record["root"], # type: ignore
|
|
157
|
+
raise_error=require_empty,
|
|
158
|
+
)
|
|
159
|
+
ssettings = StorageSettings(storage_record["root"]) # type: ignore
|
|
160
|
+
if ssettings._mark_storage_root.exists():
|
|
161
|
+
ssettings._mark_storage_root.unlink(
|
|
162
|
+
missing_ok=True # this is totally weird, but needed on Py3.11
|
|
163
|
+
)
|
|
135
164
|
logger.info(f"deleting instance {instance_slug}")
|
|
136
165
|
# below we can skip check_storage_is_empty() because we already called
|
|
137
166
|
# it above
|
|
138
|
-
|
|
167
|
+
if settings.user.handle != "anonymous":
|
|
168
|
+
delete_instance_on_hub(isettings._id, require_empty=False)
|
|
139
169
|
delete_by_isettings(isettings)
|
|
140
|
-
if
|
|
170
|
+
# if .lndb file was delete, then we might count -1
|
|
171
|
+
if n_objects <= 0 and isettings.storage.type == "local":
|
|
141
172
|
# dir is only empty after sqlite file was delete via delete_by_isettings
|
|
142
|
-
(isettings.storage.root / ".lamindb").
|
|
143
|
-
|
|
173
|
+
if (isettings.storage.root / ".lamindb").exists():
|
|
174
|
+
(isettings.storage.root / ".lamindb").rmdir()
|
|
175
|
+
if isettings.storage.root.exists():
|
|
176
|
+
isettings.storage.root.rmdir()
|
|
144
177
|
return None
|
lamindb_setup/_django.py
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from typing import Optional
|
|
4
|
+
|
|
2
5
|
from .core._settings import settings
|
|
3
6
|
from .core.django import setup_django
|
|
4
7
|
|
|
5
8
|
|
|
6
|
-
def django(command: str, package_name:
|
|
9
|
+
def django(command: str, package_name: str | None = None, **kwargs):
|
|
7
10
|
r"""Manage migrations.
|
|
8
11
|
|
|
9
12
|
Examples:
|
lamindb_setup/_exportdb.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
from
|
|
2
|
-
from importlib import import_module
|
|
1
|
+
from __future__ import annotations
|
|
3
2
|
|
|
3
|
+
from importlib import import_module
|
|
4
|
+
from pathlib import Path
|
|
4
5
|
|
|
5
6
|
MODELS = {
|
|
6
7
|
"core": {
|
|
@@ -46,6 +47,7 @@ def exportdb() -> None:
|
|
|
46
47
|
directory = Path("./lamindb_export/")
|
|
47
48
|
directory.mkdir(parents=True, exist_ok=True)
|
|
48
49
|
import pandas as pd
|
|
50
|
+
|
|
49
51
|
import lamindb_setup as ln_setup
|
|
50
52
|
|
|
51
53
|
def export_registry(registry, directory):
|
lamindb_setup/_importdb.py
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from importlib import import_module
|
|
1
4
|
from pathlib import Path
|
|
5
|
+
|
|
2
6
|
from ._exportdb import MODELS
|
|
3
|
-
from importlib import import_module
|
|
4
7
|
|
|
5
8
|
|
|
6
9
|
def import_registry(registry, directory, connection):
|
|
@@ -26,6 +29,7 @@ def importdb() -> None:
|
|
|
26
29
|
if response != "y":
|
|
27
30
|
return None
|
|
28
31
|
from sqlalchemy import create_engine, text
|
|
32
|
+
|
|
29
33
|
import lamindb_setup as ln_setup
|
|
30
34
|
|
|
31
35
|
engine = create_engine(ln_setup.settings.instance.db, echo=False)
|