linkml-store 0.0.0__py3-none-any.whl → 0.1.6__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.
Potentially problematic release.
This version of linkml-store might be problematic. Click here for more details.
- linkml_store/api/__init__.py +2 -2
- linkml_store/api/client.py +108 -7
- linkml_store/api/collection.py +221 -30
- linkml_store/api/config.py +97 -0
- linkml_store/api/database.py +207 -17
- linkml_store/api/queries.py +12 -1
- linkml_store/api/stores/chromadb/__init__.py +0 -0
- linkml_store/api/stores/chromadb/chromadb_collection.py +114 -0
- linkml_store/api/stores/chromadb/chromadb_database.py +89 -0
- linkml_store/api/stores/duckdb/duckdb_collection.py +47 -14
- linkml_store/api/stores/duckdb/duckdb_database.py +35 -44
- linkml_store/api/stores/hdf5/__init__.py +0 -0
- linkml_store/api/stores/hdf5/hdf5_collection.py +104 -0
- linkml_store/api/stores/hdf5/hdf5_database.py +79 -0
- linkml_store/api/stores/mongodb/mongodb_collection.py +86 -40
- linkml_store/api/stores/mongodb/mongodb_database.py +58 -67
- linkml_store/api/stores/solr/solr_collection.py +132 -0
- linkml_store/api/stores/solr/solr_database.py +82 -0
- linkml_store/api/stores/solr/solr_utils.py +0 -0
- linkml_store/cli.py +369 -0
- linkml_store/index/__init__.py +33 -0
- linkml_store/index/implementations/{llm_index.py → llm_indexer.py} +2 -2
- linkml_store/index/implementations/{simple_index.py → simple_indexer.py} +6 -3
- linkml_store/index/{index.py → indexer.py} +7 -4
- linkml_store/utils/format_utils.py +93 -0
- linkml_store/utils/object_utils.py +73 -0
- linkml_store/utils/sql_utils.py +46 -7
- {linkml_store-0.0.0.dist-info → linkml_store-0.1.6.dist-info}/METADATA +17 -6
- linkml_store-0.1.6.dist-info/RECORD +41 -0
- linkml_store-0.1.6.dist-info/entry_points.txt +3 -0
- linkml_store/api/metadata.py +0 -5
- linkml_store-0.0.0.dist-info/RECORD +0 -29
- linkml_store-0.0.0.dist-info/entry_points.txt +0 -3
- {linkml_store-0.0.0.dist-info → linkml_store-0.1.6.dist-info}/LICENSE +0 -0
- {linkml_store-0.0.0.dist-info → linkml_store-0.1.6.dist-info}/WHEEL +0 -0
linkml_store/utils/sql_utils.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Optional, Tuple, Type, Union
|
|
2
|
+
from typing import Any, Optional, Tuple, Type, Union
|
|
3
3
|
|
|
4
4
|
import sqlalchemy
|
|
5
5
|
import sqlalchemy.sql.sqltypes as sqlt
|
|
@@ -17,6 +17,12 @@ TYPE_MAP = {
|
|
|
17
17
|
sqlt.FLOAT: "float",
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
OP_MAP = {
|
|
21
|
+
"eq": "=",
|
|
22
|
+
"in": "ARRAY_CONTAINS",
|
|
23
|
+
"$contains": "ARRAY_CONTAINS",
|
|
24
|
+
}
|
|
25
|
+
|
|
20
26
|
|
|
21
27
|
def _map_type(typ: Type) -> str:
|
|
22
28
|
for k, v in TYPE_MAP.items():
|
|
@@ -33,13 +39,40 @@ def where_clause_to_sql(query: Query) -> str:
|
|
|
33
39
|
elif isinstance(query.where_clause, list):
|
|
34
40
|
where_clause_sql = " AND ".join(query.where_clause)
|
|
35
41
|
elif isinstance(query.where_clause, dict):
|
|
36
|
-
|
|
37
|
-
|
|
42
|
+
conjs = []
|
|
43
|
+
for k, v in query.where_clause.items():
|
|
44
|
+
conjs.extend(col_val_constraints_to_conjs(k, v))
|
|
45
|
+
where_clause_sql = " AND ".join(conjs)
|
|
46
|
+
|
|
38
47
|
else:
|
|
39
48
|
raise ValueError(f"Invalid where_clause type: {type(query.where_clause)}")
|
|
40
49
|
return "WHERE " + where_clause_sql
|
|
41
50
|
|
|
42
51
|
|
|
52
|
+
def col_val_constraints_to_conjs(col_name: str, val_constraints: Any) -> list:
|
|
53
|
+
if val_constraints is None:
|
|
54
|
+
return []
|
|
55
|
+
|
|
56
|
+
def _quote(v: Any):
|
|
57
|
+
if isinstance(v, str):
|
|
58
|
+
# escape internal vs
|
|
59
|
+
v = v.replace("'", "''")
|
|
60
|
+
return f"'{v}'"
|
|
61
|
+
else:
|
|
62
|
+
return v
|
|
63
|
+
|
|
64
|
+
if isinstance(val_constraints, dict):
|
|
65
|
+
conjs = []
|
|
66
|
+
for k, v in val_constraints.items():
|
|
67
|
+
if k in OP_MAP:
|
|
68
|
+
conjs.append(f"{OP_MAP[k]}({col_name}, {_quote(v)})")
|
|
69
|
+
else:
|
|
70
|
+
conjs.append(f"{col_name} {k} {_quote(v)}")
|
|
71
|
+
return conjs
|
|
72
|
+
else:
|
|
73
|
+
return [f"{col_name} = {_quote(val_constraints)}"]
|
|
74
|
+
|
|
75
|
+
|
|
43
76
|
def query_to_sql(query: Query, count=False, limit=None, offset: Optional[int] = None):
|
|
44
77
|
select_cols = query.select_cols if query.select_cols else ["*"]
|
|
45
78
|
if count:
|
|
@@ -67,7 +100,7 @@ def query_to_sql(query: Query, count=False, limit=None, offset: Optional[int] =
|
|
|
67
100
|
return "\n".join(sql_str)
|
|
68
101
|
|
|
69
102
|
|
|
70
|
-
def facet_count_sql(query: Query, facet_column: Union[str, Tuple[str, ...]], multivalued=False) -> str:
|
|
103
|
+
def facet_count_sql(query: Query, facet_column: Union[str, Tuple[str, ...]], multivalued=False, limit=100) -> str:
|
|
71
104
|
# Create a modified WHERE clause that excludes conditions directly related to facet_column
|
|
72
105
|
modified_where = None
|
|
73
106
|
if query.where_clause:
|
|
@@ -82,12 +115,18 @@ def facet_count_sql(query: Query, facet_column: Union[str, Tuple[str, ...]], mul
|
|
|
82
115
|
facet_column = ", ".join(facet_column)
|
|
83
116
|
from_table = query.from_table
|
|
84
117
|
if multivalued:
|
|
85
|
-
from_table = f"(SELECT UNNEST({facet_column}) as {facet_column} FROM {query.from_table}
|
|
118
|
+
from_table = f"(SELECT UNNEST({facet_column}) as {facet_column} FROM {query.from_table}"
|
|
119
|
+
from_table += f" {modified_where}" if modified_where else ""
|
|
120
|
+
from_table += ")"
|
|
121
|
+
else:
|
|
122
|
+
from_table += f" {modified_where}" if modified_where else ""
|
|
86
123
|
sql_str = [f"SELECT {facet_column}, COUNT(*) as count", f"FROM {from_table}"]
|
|
87
|
-
if modified_where:
|
|
88
|
-
|
|
124
|
+
# if modified_where:
|
|
125
|
+
# sql_str.append(f"{modified_where}")
|
|
89
126
|
sql_str.append(f"GROUP BY {facet_column}")
|
|
90
127
|
sql_str.append("ORDER BY count DESC") # Optional, order by count for convenience
|
|
128
|
+
if limit is not None:
|
|
129
|
+
sql_str.append(f"LIMIT {limit}")
|
|
91
130
|
return "\n".join(sql_str)
|
|
92
131
|
|
|
93
132
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: linkml-store
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.1.6
|
|
4
4
|
Summary: linkml-store
|
|
5
5
|
License: MIT
|
|
6
6
|
Author: Author 1
|
|
@@ -14,17 +14,25 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.12
|
|
15
15
|
Provides-Extra: analytics
|
|
16
16
|
Provides-Extra: app
|
|
17
|
+
Provides-Extra: chromadb
|
|
18
|
+
Provides-Extra: h5py
|
|
17
19
|
Provides-Extra: llm
|
|
20
|
+
Provides-Extra: map
|
|
18
21
|
Provides-Extra: mongodb
|
|
19
22
|
Provides-Extra: tests
|
|
23
|
+
Provides-Extra: validation
|
|
20
24
|
Requires-Dist: black (>=24.0.0) ; extra == "tests"
|
|
25
|
+
Requires-Dist: chromadb ; extra == "chromadb"
|
|
21
26
|
Requires-Dist: click
|
|
22
27
|
Requires-Dist: duckdb (>=0.10.1,<0.11.0)
|
|
23
|
-
Requires-Dist: duckdb-engine (>=0.11.2
|
|
28
|
+
Requires-Dist: duckdb-engine (>=0.11.2)
|
|
29
|
+
Requires-Dist: h5py ; extra == "h5py"
|
|
30
|
+
Requires-Dist: linkml ; extra == "validation"
|
|
24
31
|
Requires-Dist: linkml-runtime (>=1.7.5,<2.0.0)
|
|
32
|
+
Requires-Dist: linkml_map ; extra == "map"
|
|
25
33
|
Requires-Dist: llm ; extra == "llm"
|
|
26
34
|
Requires-Dist: matplotlib ; extra == "analytics"
|
|
27
|
-
Requires-Dist: pandas (>=2.2.1
|
|
35
|
+
Requires-Dist: pandas (>=2.2.1) ; extra == "analytics"
|
|
28
36
|
Requires-Dist: plotly ; extra == "analytics"
|
|
29
37
|
Requires-Dist: pydantic (>=2.0.0,<3.0.0)
|
|
30
38
|
Requires-Dist: pymongo ; extra == "mongodb"
|
|
@@ -36,9 +44,12 @@ Description-Content-Type: text/markdown
|
|
|
36
44
|
|
|
37
45
|
# linkml-store
|
|
38
46
|
|
|
39
|
-
|
|
47
|
+
An integration layer for multiple database backends
|
|
40
48
|
|
|
41
|
-
|
|
49
|
+
Currently this software is alpha, and has only been tested with DuckDB backends. See the Tutorial for more information.
|
|
42
50
|
|
|
43
|
-
|
|
51
|
+
There is also experimental support for vector-based indexing using OpenAI test embedding via the `llm` library.
|
|
52
|
+
|
|
53
|
+
The goals of this project are to provide high level access to data stored in heterogeneous databases,
|
|
54
|
+
with optional schema management using LinkML.
|
|
44
55
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
linkml_store/__init__.py,sha256=jlU6WOUAn8cKIhzbTULmBTWpW9gZdEt7q_RI6KZN1bY,118
|
|
2
|
+
linkml_store/api/__init__.py,sha256=3CelcFEFz0y3MkQAzhQ9JxHIt1zFk6nYZxSmYTo8YZE,226
|
|
3
|
+
linkml_store/api/client.py,sha256=hoiEE3FnNvCpvJ8LrEoTjOWg_jUolbbZEVIBef0Xv7c,7551
|
|
4
|
+
linkml_store/api/collection.py,sha256=QKmiBTb9YjpRFgon1A2nurWQnIxU8uz9EPtvJT-paT8,17203
|
|
5
|
+
linkml_store/api/config.py,sha256=qXB41OrPP3dh96XnigkJiTbAH12aPcKycSUH0MV8BHM,3269
|
|
6
|
+
linkml_store/api/database.py,sha256=dXKImuXLOaBx4JiTDSuhCL6B4rOnIzY57Rg052Odupc,13701
|
|
7
|
+
linkml_store/api/queries.py,sha256=w0qnNeCH6pC9WTGoEQYd300MF6o0G3atz2YxN3WecAs,2028
|
|
8
|
+
linkml_store/api/stores/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
+
linkml_store/api/stores/chromadb/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
+
linkml_store/api/stores/chromadb/chromadb_collection.py,sha256=hiNhnUNKrsgjYZynXCkAbLssh38Xu9D59OX8ZARnWIU,4186
|
|
11
|
+
linkml_store/api/stores/chromadb/chromadb_database.py,sha256=dZA3LQE8-ZMhJQOzsUFyxehnKpFF7adR182aggfkaFY,3205
|
|
12
|
+
linkml_store/api/stores/duckdb/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
+
linkml_store/api/stores/duckdb/duckdb_collection.py,sha256=CUfZAi2Z_uQ8DywXXEKu-Of3E_9i4GOvUVnq8qnhSew,5859
|
|
14
|
+
linkml_store/api/stores/duckdb/duckdb_database.py,sha256=3Hz01lLm8-32blkITlTurF4fd4VHSAvyFKYA1v_9NfM,6591
|
|
15
|
+
linkml_store/api/stores/duckdb/mappings.py,sha256=S4MWetLpQcxOwwedXrZTqazxdaHIQXXbq4VRq9Ok4B4,123
|
|
16
|
+
linkml_store/api/stores/hdf5/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
+
linkml_store/api/stores/hdf5/hdf5_collection.py,sha256=B7kjbb9oOgxfp9KLP42PJXIyRlVoTuscn_OR-vNxyGc,3806
|
|
18
|
+
linkml_store/api/stores/hdf5/hdf5_database.py,sha256=EZbjrpaqiNDEFvoD5dZNcGBXA8z6HRNL81emueTZWNw,2714
|
|
19
|
+
linkml_store/api/stores/mongodb/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
|
+
linkml_store/api/stores/mongodb/mongodb_collection.py,sha256=OW1IhDonKyG6jkb6Kyl0ZIBr1TYKw8iiXbx2dFrvQfk,3959
|
|
21
|
+
linkml_store/api/stores/mongodb/mongodb_database.py,sha256=QAdTi8XYLsdrEvEUUKb9qolCPeEXgfecTQ1bz9GCWDg,3670
|
|
22
|
+
linkml_store/api/stores/solr/solr_collection.py,sha256=pxT67C9OU6aaoshGZGU5ZZptLZStKOTLIBd5qGTpx2I,4723
|
|
23
|
+
linkml_store/api/stores/solr/solr_database.py,sha256=7idTQL740r1wAvK21joUMz_ajM_qzLqdfPUADa7Fa7U,2876
|
|
24
|
+
linkml_store/api/stores/solr/solr_utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
|
+
linkml_store/cli.py,sha256=r6UggDS2iFC5yIhBECwn-5aKmI38SHuYIJ5TEA0-CeM,13667
|
|
26
|
+
linkml_store/constants.py,sha256=x4ZmDsfE9rZcL5WpA93uTKrRWzCD6GodYXviVzIvR38,112
|
|
27
|
+
linkml_store/index/__init__.py,sha256=k3fq2gzhoBv3_QEu4zMbEEoc0tEOUOcrEjKQVvWfASs,881
|
|
28
|
+
linkml_store/index/implementations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
|
+
linkml_store/index/implementations/llm_indexer.py,sha256=LymhrQIeik0Qe8P2b3y2Lg7Y0P0OJ8_WjFwv-hbULj8,1069
|
|
30
|
+
linkml_store/index/implementations/simple_indexer.py,sha256=CwUBb_GO_JUd-f-KW6R4i26PUV251BNTZ2cE6Qo1fH4,1251
|
|
31
|
+
linkml_store/index/indexer.py,sha256=d_QEwJ5qEx2pkNR-QJ9hAn0pyJbhZIIT83GBFKhJA6I,3462
|
|
32
|
+
linkml_store/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
33
|
+
linkml_store/utils/format_utils.py,sha256=lTrNVEywRziCjcrEeUC3hpZZo8yDQYgG-qBanQhBYrI,3081
|
|
34
|
+
linkml_store/utils/io.py,sha256=JHUrWDtlZC2jtN_PQZ4ypdGIyYlftZEN3JaCvEPs44w,884
|
|
35
|
+
linkml_store/utils/object_utils.py,sha256=8rKboygmwlk7tGgd2TffR7lfGrXXJcQ_hEpduKP_v2A,2214
|
|
36
|
+
linkml_store/utils/sql_utils.py,sha256=TeAhAHXi1GA0f2UVrxbzStwe49Q7fN0mu5WZyfDk-s8,5651
|
|
37
|
+
linkml_store-0.1.6.dist-info/LICENSE,sha256=77mDOslUnalYnuq9xQYZKtIoNEzcH9mIjvWHOKjamnE,1086
|
|
38
|
+
linkml_store-0.1.6.dist-info/METADATA,sha256=NmD8dE9YlmNI6USIP1us-2sbc5yhtXRRYGjkhukScDQ,2064
|
|
39
|
+
linkml_store-0.1.6.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
40
|
+
linkml_store-0.1.6.dist-info/entry_points.txt,sha256=6ema3OkAkUK0ux8roEeRPtSW_Tylend5BABf-xRsZiU,53
|
|
41
|
+
linkml_store-0.1.6.dist-info/RECORD,,
|
linkml_store/api/metadata.py
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
linkml_store/__init__.py,sha256=jlU6WOUAn8cKIhzbTULmBTWpW9gZdEt7q_RI6KZN1bY,118
|
|
2
|
-
linkml_store/api/__init__.py,sha256=Il3wGkN6evgc3OOWQYL7q3J-tRBs_0yQ3Nj-s6eo-0Y,284
|
|
3
|
-
linkml_store/api/client.py,sha256=6zGzhTd6zJ-V5fzLbgljI6onq_XVvaxoeyXK5d1U9wM,4353
|
|
4
|
-
linkml_store/api/collection.py,sha256=zr9iMXCJPsBOYLwO8I0dLIl01sVG4sgXtpgVdHJIVNo,11334
|
|
5
|
-
linkml_store/api/database.py,sha256=oulUxyUGfq6dMQge___dYcevunDOIlLUBGTeewRZqDs,6682
|
|
6
|
-
linkml_store/api/metadata.py,sha256=k9F6D_nuIZ0wWocj0ew2FYSKOc06CJWvwoUpHcrs7JA,69
|
|
7
|
-
linkml_store/api/queries.py,sha256=5WgI_od_Qlpiza-u-XCrxL0F3Etf6mdeCCSSxeHT0PI,1698
|
|
8
|
-
linkml_store/api/stores/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
-
linkml_store/api/stores/duckdb/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
linkml_store/api/stores/duckdb/duckdb_collection.py,sha256=3hxwnRoY8pIZuW09yi4BSRDUT_pzTo9Mj82SBTT1aNw,4194
|
|
11
|
-
linkml_store/api/stores/duckdb/duckdb_database.py,sha256=efTwzAoAc4YugBqNl9aQhlBzcPU4GDLwGQC5UPk_Uuw,6104
|
|
12
|
-
linkml_store/api/stores/duckdb/mappings.py,sha256=S4MWetLpQcxOwwedXrZTqazxdaHIQXXbq4VRq9Ok4B4,123
|
|
13
|
-
linkml_store/api/stores/mongodb/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
-
linkml_store/api/stores/mongodb/mongodb_collection.py,sha256=atFpJWTENwCBmRjtC5iWkwwV-3XnVr16A_nuXDS76Ig,2094
|
|
15
|
-
linkml_store/api/stores/mongodb/mongodb_database.py,sha256=EpiTUftXlmOC8V4lPcrGOX2xq0leqWpmPVaZGsUMESI,3984
|
|
16
|
-
linkml_store/constants.py,sha256=x4ZmDsfE9rZcL5WpA93uTKrRWzCD6GodYXviVzIvR38,112
|
|
17
|
-
linkml_store/index/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
-
linkml_store/index/implementations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
|
-
linkml_store/index/implementations/llm_index.py,sha256=JAxg1dIuU7W8ZtnsGcogbBUvyrPTZCbKhEFv-0lEKrk,1061
|
|
20
|
-
linkml_store/index/implementations/simple_index.py,sha256=ep73dg86QqV7B7t_VoOK1weVx5RD0xvJ7uJPsszd5I0,1134
|
|
21
|
-
linkml_store/index/index.py,sha256=uwgKtw76ch0qe5CbSj2Ft_WAhY94Qm5qLBJucl-VPWA,3420
|
|
22
|
-
linkml_store/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
|
-
linkml_store/utils/io.py,sha256=JHUrWDtlZC2jtN_PQZ4ypdGIyYlftZEN3JaCvEPs44w,884
|
|
24
|
-
linkml_store/utils/sql_utils.py,sha256=sCM9GqEW6zZ3-2n5tsW7gzi0DerP6TXx3AJDY_0kCJ4,4557
|
|
25
|
-
linkml_store-0.0.0.dist-info/LICENSE,sha256=77mDOslUnalYnuq9xQYZKtIoNEzcH9mIjvWHOKjamnE,1086
|
|
26
|
-
linkml_store-0.0.0.dist-info/METADATA,sha256=Ignb5ab4IwjIfm60g2yciUqYBb0IstFvABlOMFTygPk,1717
|
|
27
|
-
linkml_store-0.0.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
28
|
-
linkml_store-0.0.0.dist-info/entry_points.txt,sha256=YdXo7B96u7fP8WX9cirGelqH0kjx7vGjT-w8hq8HFSE,54
|
|
29
|
-
linkml_store-0.0.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|