linkml-store 0.1.9__tar.gz → 0.1.11__tar.gz

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.

Potentially problematic release.


This version of linkml-store might be problematic. Click here for more details.

Files changed (62) hide show
  1. linkml_store-0.1.11/PKG-INFO +171 -0
  2. linkml_store-0.1.11/README.md +115 -0
  3. {linkml_store-0.1.9 → linkml_store-0.1.11}/pyproject.toml +12 -3
  4. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/client.py +76 -11
  5. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/collection.py +223 -40
  6. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/config.py +59 -9
  7. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/database.py +45 -27
  8. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/duckdb/duckdb_collection.py +21 -3
  9. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/duckdb/duckdb_database.py +36 -3
  10. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/filesystem/filesystem_collection.py +13 -4
  11. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/filesystem/filesystem_database.py +10 -1
  12. linkml_store-0.1.11/src/linkml_store/api/stores/mongodb/mongodb_collection.py +175 -0
  13. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/mongodb/mongodb_database.py +1 -36
  14. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/solr/solr_collection.py +4 -4
  15. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/cli.py +44 -18
  16. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/index/__init__.py +21 -5
  17. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/index/implementations/llm_indexer.py +2 -1
  18. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/index/indexer.py +20 -4
  19. linkml_store-0.1.11/src/linkml_store/utils/file_utils.py +37 -0
  20. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/utils/format_utils.py +69 -8
  21. linkml_store-0.1.11/src/linkml_store/utils/pandas_utils.py +40 -0
  22. linkml_store-0.1.11/src/linkml_store/utils/schema_utils.py +23 -0
  23. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/utils/sql_utils.py +2 -1
  24. linkml_store-0.1.11/src/linkml_store/webapi/__init__.py +0 -0
  25. linkml_store-0.1.11/src/linkml_store/webapi/html/__init__.py +3 -0
  26. linkml_store-0.1.11/src/linkml_store/webapi/html/base.html.j2 +24 -0
  27. linkml_store-0.1.11/src/linkml_store/webapi/html/collection_details.html.j2 +15 -0
  28. linkml_store-0.1.11/src/linkml_store/webapi/html/database_details.html.j2 +16 -0
  29. linkml_store-0.1.11/src/linkml_store/webapi/html/databases.html.j2 +14 -0
  30. linkml_store-0.1.11/src/linkml_store/webapi/html/generic.html.j2 +46 -0
  31. linkml_store-0.1.11/src/linkml_store/webapi/main.py +572 -0
  32. linkml_store-0.1.9/PKG-INFO +0 -61
  33. linkml_store-0.1.9/README.md +0 -12
  34. linkml_store-0.1.9/src/linkml_store/api/stores/mongodb/mongodb_collection.py +0 -129
  35. {linkml_store-0.1.9 → linkml_store-0.1.11}/LICENSE +0 -0
  36. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/__init__.py +0 -0
  37. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/__init__.py +0 -0
  38. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/queries.py +0 -0
  39. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/__init__.py +0 -0
  40. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/chromadb/__init__.py +0 -0
  41. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/chromadb/chromadb_collection.py +0 -0
  42. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/chromadb/chromadb_database.py +0 -0
  43. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/duckdb/__init__.py +0 -0
  44. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/duckdb/mappings.py +0 -0
  45. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/filesystem/__init__.py +0 -0
  46. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/hdf5/__init__.py +0 -0
  47. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/hdf5/hdf5_collection.py +0 -0
  48. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/hdf5/hdf5_database.py +0 -0
  49. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/mongodb/__init__.py +0 -0
  50. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/solr/__init__.py +0 -0
  51. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/solr/solr_database.py +0 -0
  52. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/solr/solr_utils.py +0 -0
  53. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/types.py +0 -0
  54. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/constants.py +0 -0
  55. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/index/implementations/__init__.py +0 -0
  56. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/index/implementations/simple_indexer.py +0 -0
  57. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/utils/__init__.py +0 -0
  58. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/utils/change_utils.py +0 -0
  59. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/utils/io.py +0 -0
  60. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/utils/object_utils.py +0 -0
  61. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/utils/patch_utils.py +0 -0
  62. {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/utils/query_utils.py +0 -0
@@ -0,0 +1,171 @@
1
+ Metadata-Version: 2.1
2
+ Name: linkml-store
3
+ Version: 0.1.11
4
+ Summary: linkml-store
5
+ License: MIT
6
+ Author: Author 1
7
+ Author-email: author@org.org
8
+ Requires-Python: >=3.9, !=2.7.*, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*, !=3.7.*, !=3.8.*
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Provides-Extra: analytics
16
+ Provides-Extra: app
17
+ Provides-Extra: chromadb
18
+ Provides-Extra: fastapi
19
+ Provides-Extra: frictionless
20
+ Provides-Extra: h5py
21
+ Provides-Extra: llm
22
+ Provides-Extra: map
23
+ Provides-Extra: mongodb
24
+ Provides-Extra: pyarrow
25
+ Provides-Extra: renderer
26
+ Provides-Extra: tests
27
+ Provides-Extra: validation
28
+ Requires-Dist: black (>=24.0.0) ; extra == "tests"
29
+ Requires-Dist: chromadb ; extra == "chromadb"
30
+ Requires-Dist: click
31
+ Requires-Dist: duckdb (>=0.10.1,<0.11.0)
32
+ Requires-Dist: duckdb-engine (>=0.11.2)
33
+ Requires-Dist: fastapi ; extra == "fastapi"
34
+ Requires-Dist: frictionless ; extra == "frictionless"
35
+ Requires-Dist: h5py ; extra == "h5py"
36
+ Requires-Dist: jinja2 (>=3.1.4,<4.0.0)
37
+ Requires-Dist: jsonlines (>=4.0.0,<5.0.0)
38
+ Requires-Dist: linkml (>=1.8.0) ; extra == "validation"
39
+ Requires-Dist: linkml-runtime (>=1.8.0)
40
+ Requires-Dist: linkml_map ; extra == "map"
41
+ Requires-Dist: linkml_renderer ; extra == "renderer"
42
+ Requires-Dist: llm ; extra == "llm"
43
+ Requires-Dist: matplotlib ; extra == "analytics"
44
+ Requires-Dist: pandas (>=2.2.1) ; extra == "analytics"
45
+ Requires-Dist: plotly ; extra == "analytics"
46
+ Requires-Dist: pyarrow ; extra == "pyarrow"
47
+ Requires-Dist: pydantic (>=2.0.0,<3.0.0)
48
+ Requires-Dist: pymongo ; extra == "mongodb"
49
+ Requires-Dist: pystow (>=0.5.4,<0.6.0)
50
+ Requires-Dist: seaborn ; extra == "analytics"
51
+ Requires-Dist: sqlalchemy
52
+ Requires-Dist: streamlit (>=1.32.2,<2.0.0) ; extra == "app"
53
+ Requires-Dist: uvicorn ; extra == "fastapi"
54
+ Description-Content-Type: text/markdown
55
+
56
+ # linkml-store
57
+
58
+ An AI-ready data management and integration platform. LinkML-Store
59
+ provides an abstraction layer over multiple different backends
60
+ (including DuckDB, MongoDB, and local filesystems), allowing for
61
+ common query, index, and storage operations.
62
+
63
+ For full documentation, see [https://linkml.io/linkml-store/](https://linkml.io/linkml-store/)
64
+
65
+ __Warning__ LinkML-Store is still undergoing changes and refactoring,
66
+ APIs and command line options are subject to change!
67
+
68
+ ## Quick Start
69
+
70
+ Install, add data, query it:
71
+
72
+ ```
73
+ pip install linkml-store[all]
74
+ linkml-store -d duckdb:///db/my.db -c persons insert data/*.json
75
+ linkml-store -d duckdb:///db/my.db -c persons query -w "occupation: Bricklayer"
76
+ ```
77
+
78
+ Index it, search it:
79
+
80
+ ```
81
+ linkml-store -d duckdb:///db/my.db -c persons index -t llm
82
+ linkml-store -d duckdb:///db/my.db -c persons search "all persons employed in construction"
83
+ ```
84
+
85
+ Validate it:
86
+
87
+ ```
88
+ linkml-store -d duckdb:///db/my.db -c persons validate
89
+ ```
90
+
91
+ ## Basic usage
92
+
93
+ * [Command Line](https://linkml.io/linkml-store/tutorials/Command-Line-Tutorial.html)
94
+ * [Python](https://linkml.io/linkml-store/tutorials/Python-Tutorial.html)
95
+ * API
96
+ * Streamlit applications
97
+
98
+ ## Features
99
+
100
+ ### Multiple Adapters
101
+
102
+ LinkML-Store is designed to work with multiple backends, giving a common abstraction layer
103
+
104
+ * [MongoDB](https://linkml.io/linkml-store/how-to/Use-MongoDB.html)
105
+ * [DuckDB](https://linkml.io/linkml-store/tutorials/Python-Tutorial.html)
106
+ * [Solr](https://linkml.io/linkml-store/how-to/Query-Solr-using-CLI.html)
107
+ * Filesystem
108
+
109
+ Coming soon: any RDBMS, any triplestore, Neo4J, HDF5-based stores, ChromaDB/Vector dbs ...
110
+
111
+ The intent is to give a union of all features of each backend. For
112
+ example, analytic faceted queries are provided for *all* backends, not
113
+ just Solr.
114
+
115
+ ### Composable indexes
116
+
117
+ Many backends come with their own indexing and search
118
+ schemes. Classically this was Lucene-based indexes, now it is semantic
119
+ search using LLM embeddings.
120
+
121
+ LinkML store treats indexing as an orthogonal concern - you can
122
+ compose different indexing schemes with different backends. You don't
123
+ need to have a vector database to run embedding search!
124
+
125
+ See [How to Use-Semantic-Search](https://linkml.io/linkml-store/how-to/Use-Semantic-Search.html)
126
+
127
+ ### Use with LLMs
128
+
129
+ TODO - docs
130
+
131
+ ### Validation
132
+
133
+ LinkML-Store is backed by [LinkML](https://linkml.io), which allows
134
+ for powerful expressive structural and semantic constraints.
135
+
136
+ See [Indexing JSON](https://linkml.io/linkml-store/how-to/Index-Phenopackets.html)
137
+
138
+ and [Referential Integrity](https://linkml.io/linkml-store/how-to/Check-Referential-Integrity.html)
139
+
140
+ ## Web API
141
+
142
+ There is a preliminary API following HATEOAS principles implemented using FastAPI.
143
+
144
+ To start you should first create a config file, e.g. `db/conf.yaml`:
145
+
146
+ Then run:
147
+
148
+ ```
149
+ export LINKML_STORE_CONFIG=./db/conf.yaml
150
+ make api
151
+ ```
152
+
153
+ The API returns links as well as data objects, it's recommended to use a Chrome plugin for JSON viewing
154
+ for exploring the API. TODO: add docs here.
155
+
156
+ The main endpoints are:
157
+
158
+ * `http://localhost:8000/` - the root of the API
159
+ * `http://localhost:8000/pages/` - browse the API via HTML
160
+ * `http://localhost:8000/docs` - the Swagger UI
161
+
162
+ ## Streamlit app
163
+
164
+ ```
165
+ make app
166
+ ```
167
+
168
+ ## Background
169
+
170
+ See [these slides](https://docs.google.com/presentation/d/e/2PACX-1vSgtWUNUW0qNO_ZhMAGQ6fYhlXZJjBNMYT0OiZz8DDx8oj7iG9KofRs6SeaMXBBOICGknoyMG2zaHnm/embed?start=false&loop=false&delayms=3000) for more details
171
+
@@ -0,0 +1,115 @@
1
+ # linkml-store
2
+
3
+ An AI-ready data management and integration platform. LinkML-Store
4
+ provides an abstraction layer over multiple different backends
5
+ (including DuckDB, MongoDB, and local filesystems), allowing for
6
+ common query, index, and storage operations.
7
+
8
+ For full documentation, see [https://linkml.io/linkml-store/](https://linkml.io/linkml-store/)
9
+
10
+ __Warning__ LinkML-Store is still undergoing changes and refactoring,
11
+ APIs and command line options are subject to change!
12
+
13
+ ## Quick Start
14
+
15
+ Install, add data, query it:
16
+
17
+ ```
18
+ pip install linkml-store[all]
19
+ linkml-store -d duckdb:///db/my.db -c persons insert data/*.json
20
+ linkml-store -d duckdb:///db/my.db -c persons query -w "occupation: Bricklayer"
21
+ ```
22
+
23
+ Index it, search it:
24
+
25
+ ```
26
+ linkml-store -d duckdb:///db/my.db -c persons index -t llm
27
+ linkml-store -d duckdb:///db/my.db -c persons search "all persons employed in construction"
28
+ ```
29
+
30
+ Validate it:
31
+
32
+ ```
33
+ linkml-store -d duckdb:///db/my.db -c persons validate
34
+ ```
35
+
36
+ ## Basic usage
37
+
38
+ * [Command Line](https://linkml.io/linkml-store/tutorials/Command-Line-Tutorial.html)
39
+ * [Python](https://linkml.io/linkml-store/tutorials/Python-Tutorial.html)
40
+ * API
41
+ * Streamlit applications
42
+
43
+ ## Features
44
+
45
+ ### Multiple Adapters
46
+
47
+ LinkML-Store is designed to work with multiple backends, giving a common abstraction layer
48
+
49
+ * [MongoDB](https://linkml.io/linkml-store/how-to/Use-MongoDB.html)
50
+ * [DuckDB](https://linkml.io/linkml-store/tutorials/Python-Tutorial.html)
51
+ * [Solr](https://linkml.io/linkml-store/how-to/Query-Solr-using-CLI.html)
52
+ * Filesystem
53
+
54
+ Coming soon: any RDBMS, any triplestore, Neo4J, HDF5-based stores, ChromaDB/Vector dbs ...
55
+
56
+ The intent is to give a union of all features of each backend. For
57
+ example, analytic faceted queries are provided for *all* backends, not
58
+ just Solr.
59
+
60
+ ### Composable indexes
61
+
62
+ Many backends come with their own indexing and search
63
+ schemes. Classically this was Lucene-based indexes, now it is semantic
64
+ search using LLM embeddings.
65
+
66
+ LinkML store treats indexing as an orthogonal concern - you can
67
+ compose different indexing schemes with different backends. You don't
68
+ need to have a vector database to run embedding search!
69
+
70
+ See [How to Use-Semantic-Search](https://linkml.io/linkml-store/how-to/Use-Semantic-Search.html)
71
+
72
+ ### Use with LLMs
73
+
74
+ TODO - docs
75
+
76
+ ### Validation
77
+
78
+ LinkML-Store is backed by [LinkML](https://linkml.io), which allows
79
+ for powerful expressive structural and semantic constraints.
80
+
81
+ See [Indexing JSON](https://linkml.io/linkml-store/how-to/Index-Phenopackets.html)
82
+
83
+ and [Referential Integrity](https://linkml.io/linkml-store/how-to/Check-Referential-Integrity.html)
84
+
85
+ ## Web API
86
+
87
+ There is a preliminary API following HATEOAS principles implemented using FastAPI.
88
+
89
+ To start you should first create a config file, e.g. `db/conf.yaml`:
90
+
91
+ Then run:
92
+
93
+ ```
94
+ export LINKML_STORE_CONFIG=./db/conf.yaml
95
+ make api
96
+ ```
97
+
98
+ The API returns links as well as data objects, it's recommended to use a Chrome plugin for JSON viewing
99
+ for exploring the API. TODO: add docs here.
100
+
101
+ The main endpoints are:
102
+
103
+ * `http://localhost:8000/` - the root of the API
104
+ * `http://localhost:8000/pages/` - browse the API via HTML
105
+ * `http://localhost:8000/docs` - the Swagger UI
106
+
107
+ ## Streamlit app
108
+
109
+ ```
110
+ make app
111
+ ```
112
+
113
+ ## Background
114
+
115
+ See [these slides](https://docs.google.com/presentation/d/e/2PACX-1vSgtWUNUW0qNO_ZhMAGQ6fYhlXZJjBNMYT0OiZz8DDx8oj7iG9KofRs6SeaMXBBOICGknoyMG2zaHnm/embed?start=false&loop=false&delayms=3000) for more details
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "linkml-store"
3
- version = "0.1.9"
3
+ version = "0.1.11"
4
4
  description = "linkml-store"
5
5
  authors = ["Author 1 <author@org.org>"]
6
6
  license = "MIT"
@@ -10,7 +10,7 @@ readme = "README.md"
10
10
  python = "^3.9, !=3.9.7"
11
11
  click = "*"
12
12
  pydantic = "^2.0.0"
13
- linkml-runtime = "^1.7.5"
13
+ linkml-runtime = ">=1.8.0"
14
14
  streamlit = { version = "^1.32.2", optional = true }
15
15
  sqlalchemy = "*"
16
16
  duckdb = "^0.10.1"
@@ -25,11 +25,15 @@ pymongo = { version="*", optional = true }
25
25
  chromadb = { version="*", optional = true }
26
26
  pyarrow = { version="*", optional = true }
27
27
  h5py = { version="*", optional = true }
28
- linkml = { version="*", optional = true }
28
+ linkml = { version=">=1.8.0", optional = true }
29
29
  linkml_map = { version="*", optional = true }
30
+ linkml_renderer = { version="*", optional = true }
31
+ frictionless = { version="*", optional = true }
30
32
  pandas = ">=2.2.1"
31
33
  jinja2 = "^3.1.4"
32
34
  jsonlines = "^4.0.0"
35
+ fastapi = { version="*", optional = true }
36
+ uvicorn = { version="*", optional = true }
33
37
 
34
38
  [tool.poetry.group.dev.dependencies]
35
39
  pytest = {version = ">=7.1.2"}
@@ -46,6 +50,7 @@ nbsphinx = "*"
46
50
  jupyter = "*"
47
51
  jupysql = "*"
48
52
  papermill = "*"
53
+ nbdime = "*"
49
54
 
50
55
  [tool.poetry.group.tests.dependencies]
51
56
  pytest = "^7.4.0"
@@ -66,9 +71,13 @@ h5py = ["h5py"]
66
71
  pyarrow = ["pyarrow"]
67
72
  validation = ["linkml"]
68
73
  map = ["linkml_map"]
74
+ renderer = ["linkml_renderer"]
75
+ fastapi = ["fastapi", "uvicorn"]
76
+ frictionless = ["frictionless"]
69
77
 
70
78
  [tool.poetry.scripts]
71
79
  linkml-store = "linkml_store.cli:cli"
80
+ linkml-store-api = "linkml_store.webapi.main:start"
72
81
 
73
82
  [tool.poetry-dynamic-versioning]
74
83
  enable = false
@@ -98,7 +98,7 @@ class Client:
98
98
  """
99
99
  return self.metadata.base_dir
100
100
 
101
- def from_config(self, config: Union[ClientConfig, str, Path], base_dir=None, **kwargs):
101
+ def from_config(self, config: Union[ClientConfig, dict, str, Path], base_dir=None, **kwargs):
102
102
  """
103
103
  Create a client from a configuration.
104
104
 
@@ -118,11 +118,13 @@ class Client:
118
118
  :return:
119
119
 
120
120
  """
121
+ if isinstance(config, dict):
122
+ config = ClientConfig(**config)
121
123
  if isinstance(config, Path):
122
124
  config = str(config)
123
125
  if isinstance(config, str):
124
- if not base_dir:
125
- base_dir = Path(config).parent
126
+ # if not base_dir:
127
+ # base_dir = Path(config).parent
126
128
  parsed_obj = yaml.safe_load(open(config))
127
129
  config = ClientConfig(**parsed_obj)
128
130
  self.metadata = config
@@ -133,8 +135,15 @@ class Client:
133
135
 
134
136
  def _initialize_databases(self, **kwargs):
135
137
  for name, db_config in self.metadata.databases.items():
136
- handle = db_config.handle.format(base_dir=self.base_dir)
138
+ base_dir = self.base_dir
139
+ logger.info(f"Initializing database: {name}, base_dir: {base_dir}")
140
+ if not base_dir:
141
+ base_dir = Path.cwd()
142
+ logger.info(f"Using current working directory: {base_dir}")
143
+ handle = db_config.handle.format(base_dir=base_dir)
137
144
  db_config.handle = handle
145
+ if db_config.schema_location:
146
+ db_config.schema_location = db_config.schema_location.format(base_dir=base_dir)
138
147
  db = self.attach_database(handle, alias=name, **kwargs)
139
148
  db.from_config(db_config)
140
149
 
@@ -233,7 +242,7 @@ class Client:
233
242
  Return all attached databases
234
243
 
235
244
  Examples
236
- --------
245
+
237
246
  >>> client = Client()
238
247
  >>> _ = client.attach_database("duckdb", alias="test1")
239
248
  >>> _ = client.attach_database("duckdb", alias="test2")
@@ -259,25 +268,81 @@ class Client:
259
268
  """
260
269
  Drop a database.
261
270
 
271
+ Example (in-memory):
272
+
273
+ >>> client = Client()
274
+ >>> db1 = client.attach_database("duckdb", alias="test1")
275
+ >>> db2 = client.attach_database("duckdb", alias="test2")
276
+ >>> len(client.databases)
277
+ 2
278
+ >>> client.drop_database("test1")
279
+ >>> len(client.databases)
280
+ 1
281
+
282
+ Databases that persist on disk:
283
+
284
+ >>> client = Client()
285
+ >>> path = Path("tmp/test.db")
286
+ >>> path.parent.mkdir(parents=True, exist_ok=True)
287
+ >>> db = client.attach_database(f"duckdb:///{path}", alias="test")
288
+ >>> len(client.databases)
289
+ 1
290
+ >>> db.store({"persons": [{"id": "P1", "name": "John"}]})
291
+ >>> db.commit()
292
+ >>> Path("tmp/test.db").exists()
293
+ True
294
+ >>> client.drop_database("test")
295
+ >>> len(client.databases)
296
+ 0
297
+ >>> Path("tmp/test.db").exists()
298
+ False
299
+
300
+ Dropping a non-existent database:
301
+
302
+ >>> client = Client()
303
+ >>> client.drop_database("duckdb:///tmp/made-up1", missing_ok=True)
304
+ >>> client.drop_database("duckdb:///tmp/made-up2", missing_ok=False)
305
+ Traceback (most recent call last):
306
+ ...
307
+ ValueError: Database duckdb:///tmp/made-up2 not found
308
+
262
309
  :param name:
263
310
  :param missing_ok:
264
311
  :return:
265
312
  """
266
- if name in self._databases:
267
- db = self._databases[name]
268
- db.drop(**kwargs)
269
- del self._databases[name]
313
+ if self._databases:
314
+ if name in self._databases:
315
+ db = self._databases[name]
316
+ db.drop(**kwargs)
317
+ del self._databases[name]
318
+ else:
319
+ if not missing_ok:
320
+ raise ValueError(f"Database {name} not found")
270
321
  else:
271
- if not missing_ok:
272
- raise ValueError(f"Database {name} not found")
322
+ db = self.get_database(name, create_if_not_exists=True)
323
+ db.drop(**kwargs)
273
324
 
274
325
  def drop_all_databases(self, **kwargs):
275
326
  """
276
327
  Drop all databases.
277
328
 
329
+ Example (in-memory):
330
+
331
+ >>> client = Client()
332
+ >>> db1 = client.attach_database("duckdb", alias="test1")
333
+ >>> assert "test1" in client.databases
334
+ >>> db2 = client.attach_database("duckdb", alias="test2")
335
+ >>> assert "test2" in client.databases
336
+ >>> client.drop_all_databases()
337
+ >>> len(client.databases)
338
+ 0
339
+
340
+
278
341
  :param missing_ok:
279
342
  :return:
280
343
  """
344
+ if not self._databases:
345
+ return
281
346
  for name in list(self._databases.keys()):
282
347
  self.drop_database(name, missing_ok=False, **kwargs)
283
348
  self._databases = {}