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.

Files changed (35) hide show
  1. linkml_store/api/__init__.py +2 -2
  2. linkml_store/api/client.py +108 -7
  3. linkml_store/api/collection.py +221 -30
  4. linkml_store/api/config.py +97 -0
  5. linkml_store/api/database.py +207 -17
  6. linkml_store/api/queries.py +12 -1
  7. linkml_store/api/stores/chromadb/__init__.py +0 -0
  8. linkml_store/api/stores/chromadb/chromadb_collection.py +114 -0
  9. linkml_store/api/stores/chromadb/chromadb_database.py +89 -0
  10. linkml_store/api/stores/duckdb/duckdb_collection.py +47 -14
  11. linkml_store/api/stores/duckdb/duckdb_database.py +35 -44
  12. linkml_store/api/stores/hdf5/__init__.py +0 -0
  13. linkml_store/api/stores/hdf5/hdf5_collection.py +104 -0
  14. linkml_store/api/stores/hdf5/hdf5_database.py +79 -0
  15. linkml_store/api/stores/mongodb/mongodb_collection.py +86 -40
  16. linkml_store/api/stores/mongodb/mongodb_database.py +58 -67
  17. linkml_store/api/stores/solr/solr_collection.py +132 -0
  18. linkml_store/api/stores/solr/solr_database.py +82 -0
  19. linkml_store/api/stores/solr/solr_utils.py +0 -0
  20. linkml_store/cli.py +369 -0
  21. linkml_store/index/__init__.py +33 -0
  22. linkml_store/index/implementations/{llm_index.py → llm_indexer.py} +2 -2
  23. linkml_store/index/implementations/{simple_index.py → simple_indexer.py} +6 -3
  24. linkml_store/index/{index.py → indexer.py} +7 -4
  25. linkml_store/utils/format_utils.py +93 -0
  26. linkml_store/utils/object_utils.py +73 -0
  27. linkml_store/utils/sql_utils.py +46 -7
  28. {linkml_store-0.0.0.dist-info → linkml_store-0.1.6.dist-info}/METADATA +17 -6
  29. linkml_store-0.1.6.dist-info/RECORD +41 -0
  30. linkml_store-0.1.6.dist-info/entry_points.txt +3 -0
  31. linkml_store/api/metadata.py +0 -5
  32. linkml_store-0.0.0.dist-info/RECORD +0 -29
  33. linkml_store-0.0.0.dist-info/entry_points.txt +0 -3
  34. {linkml_store-0.0.0.dist-info → linkml_store-0.1.6.dist-info}/LICENSE +0 -0
  35. {linkml_store-0.0.0.dist-info → linkml_store-0.1.6.dist-info}/WHEEL +0 -0
@@ -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
- # TODO: bobby tables
37
- where_clause_sql = " AND ".join([f"{k} = '{v}'" for k, v in query.where_clause.items()])
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
- sql_str.append(f"{modified_where}")
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.0.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,<0.12.0)
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,<3.0.0) ; extra == "analytics"
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
- This is the project description.
47
+ An integration layer for multiple database backends
40
48
 
41
- # Acknowledgements
49
+ Currently this software is alpha, and has only been tested with DuckDB backends. See the Tutorial for more information.
42
50
 
43
- This [cookiecutter](https://cookiecutter.readthedocs.io/en/stable/README.html) project was developed from the [monarch-project-template](https://github.com/monarch-initiative/monarch-project-template) template and will be kept up-to-date using [cruft](https://cruft.github.io/cruft/).
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,,
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ linkml-store=linkml_store.cli:cli
3
+
@@ -1,5 +0,0 @@
1
- from pydantic import BaseModel
2
-
3
-
4
- class MetaData(BaseModel):
5
- pass
@@ -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,,
@@ -1,3 +0,0 @@
1
- [console_scripts]
2
- linkml-store=linkml_store.cli:main
3
-