llama-index-vector-stores-postgres 0.4.0__tar.gz → 0.4.2__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.
- {llama_index_vector_stores_postgres-0.4.0 → llama_index_vector_stores_postgres-0.4.2}/PKG-INFO +2 -2
- {llama_index_vector_stores_postgres-0.4.0 → llama_index_vector_stores_postgres-0.4.2}/llama_index/vector_stores/postgres/base.py +41 -6
- {llama_index_vector_stores_postgres-0.4.0 → llama_index_vector_stores_postgres-0.4.2}/pyproject.toml +2 -2
- {llama_index_vector_stores_postgres-0.4.0 → llama_index_vector_stores_postgres-0.4.2}/README.md +0 -0
- {llama_index_vector_stores_postgres-0.4.0 → llama_index_vector_stores_postgres-0.4.2}/llama_index/py.typed +0 -0
- {llama_index_vector_stores_postgres-0.4.0 → llama_index_vector_stores_postgres-0.4.2}/llama_index/vector_stores/postgres/__init__.py +0 -0
{llama_index_vector_stores_postgres-0.4.0 → llama_index_vector_stores_postgres-0.4.2}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: llama-index-vector-stores-postgres
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
4
4
|
Summary: llama-index vector_stores postgres integration
|
|
5
5
|
License: MIT
|
|
6
6
|
Author: Your Name
|
|
@@ -13,7 +13,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.11
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.12
|
|
15
15
|
Requires-Dist: asyncpg (>=0.29.0,<1.0.0)
|
|
16
|
-
Requires-Dist: llama-index-core (>=0.12.
|
|
16
|
+
Requires-Dist: llama-index-core (>=0.12.6,<0.13.0)
|
|
17
17
|
Requires-Dist: pgvector (>=0.3.6,<1.0.0)
|
|
18
18
|
Requires-Dist: psycopg2-binary (>=2.9.9,<3.0.0)
|
|
19
19
|
Requires-Dist: sqlalchemy[asyncio] (>=1.4.49,<2.1)
|
|
@@ -4,6 +4,7 @@ from typing import Any, Dict, List, NamedTuple, Optional, Type, Union, TYPE_CHEC
|
|
|
4
4
|
|
|
5
5
|
import asyncpg # noqa
|
|
6
6
|
import pgvector # noqa
|
|
7
|
+
from pgvector.sqlalchemy import HALFVEC
|
|
7
8
|
import psycopg2 # noqa
|
|
8
9
|
import sqlalchemy
|
|
9
10
|
import sqlalchemy.ext.asyncio
|
|
@@ -46,6 +47,7 @@ def get_data_model(
|
|
|
46
47
|
cache_okay: bool,
|
|
47
48
|
embed_dim: int = 1536,
|
|
48
49
|
use_jsonb: bool = False,
|
|
50
|
+
use_halfvec: bool = False,
|
|
49
51
|
) -> Any:
|
|
50
52
|
"""
|
|
51
53
|
This part create a dynamic sqlalchemy model with a new table.
|
|
@@ -66,6 +68,11 @@ def get_data_model(
|
|
|
66
68
|
|
|
67
69
|
metadata_dtype = JSONB if use_jsonb else JSON
|
|
68
70
|
|
|
71
|
+
if use_halfvec:
|
|
72
|
+
embedding_col = Column(HALFVEC(embed_dim)) # type: ignore
|
|
73
|
+
else:
|
|
74
|
+
embedding_col = Column(Vector(embed_dim)) # type: ignore
|
|
75
|
+
|
|
69
76
|
if hybrid_search:
|
|
70
77
|
|
|
71
78
|
class HybridAbstractData(base): # type: ignore
|
|
@@ -74,7 +81,7 @@ def get_data_model(
|
|
|
74
81
|
text = Column(VARCHAR, nullable=False)
|
|
75
82
|
metadata_ = Column(metadata_dtype)
|
|
76
83
|
node_id = Column(VARCHAR)
|
|
77
|
-
embedding =
|
|
84
|
+
embedding = embedding_col
|
|
78
85
|
text_search_tsv = Column( # type: ignore
|
|
79
86
|
TSVector(),
|
|
80
87
|
Computed(
|
|
@@ -101,7 +108,7 @@ def get_data_model(
|
|
|
101
108
|
text = Column(VARCHAR, nullable=False)
|
|
102
109
|
metadata_ = Column(metadata_dtype)
|
|
103
110
|
node_id = Column(VARCHAR)
|
|
104
|
-
embedding =
|
|
111
|
+
embedding = embedding_col
|
|
105
112
|
|
|
106
113
|
model = type(
|
|
107
114
|
class_name,
|
|
@@ -130,6 +137,8 @@ class PGVectorStore(BasePydanticVectorStore):
|
|
|
130
137
|
user="postgres",
|
|
131
138
|
table_name="paul_graham_essay",
|
|
132
139
|
embed_dim=1536 # openai embedding dimension
|
|
140
|
+
use_halfvec=True # Enable half precision
|
|
141
|
+
|
|
133
142
|
)
|
|
134
143
|
```
|
|
135
144
|
"""
|
|
@@ -153,6 +162,8 @@ class PGVectorStore(BasePydanticVectorStore):
|
|
|
153
162
|
|
|
154
163
|
hnsw_kwargs: Optional[Dict[str, Any]]
|
|
155
164
|
|
|
165
|
+
use_halfvec: bool = False
|
|
166
|
+
|
|
156
167
|
_base: Any = PrivateAttr()
|
|
157
168
|
_table_class: Any = PrivateAttr()
|
|
158
169
|
_engine: Any = PrivateAttr()
|
|
@@ -177,6 +188,7 @@ class PGVectorStore(BasePydanticVectorStore):
|
|
|
177
188
|
hnsw_kwargs: Optional[Dict[str, Any]] = None,
|
|
178
189
|
create_engine_kwargs: Optional[Dict[str, Any]] = None,
|
|
179
190
|
initialization_fail_on_error: bool = False,
|
|
191
|
+
use_halfvec: bool = False,
|
|
180
192
|
) -> None:
|
|
181
193
|
"""Constructor.
|
|
182
194
|
|
|
@@ -196,6 +208,7 @@ class PGVectorStore(BasePydanticVectorStore):
|
|
|
196
208
|
contains "hnsw_ef_construction", "hnsw_ef_search", "hnsw_m", and optionally "hnsw_dist_method". Defaults to None,
|
|
197
209
|
which turns off HNSW search.
|
|
198
210
|
create_engine_kwargs (Optional[Dict[str, Any]], optional): Engine parameters to pass to create_engine. Defaults to None.
|
|
211
|
+
use_halfvec (bool, optional): If `True`, use half-precision vectors. Defaults to False.
|
|
199
212
|
"""
|
|
200
213
|
table_name = table_name.lower()
|
|
201
214
|
schema_name = schema_name.lower()
|
|
@@ -223,6 +236,7 @@ class PGVectorStore(BasePydanticVectorStore):
|
|
|
223
236
|
hnsw_kwargs=hnsw_kwargs,
|
|
224
237
|
create_engine_kwargs=create_engine_kwargs or {},
|
|
225
238
|
initialization_fail_on_error=initialization_fail_on_error,
|
|
239
|
+
use_halfvec=use_halfvec,
|
|
226
240
|
)
|
|
227
241
|
|
|
228
242
|
# sqlalchemy model
|
|
@@ -236,6 +250,7 @@ class PGVectorStore(BasePydanticVectorStore):
|
|
|
236
250
|
cache_ok,
|
|
237
251
|
embed_dim=embed_dim,
|
|
238
252
|
use_jsonb=use_jsonb,
|
|
253
|
+
use_halfvec=use_halfvec,
|
|
239
254
|
)
|
|
240
255
|
|
|
241
256
|
async def close(self) -> None:
|
|
@@ -272,6 +287,7 @@ class PGVectorStore(BasePydanticVectorStore):
|
|
|
272
287
|
use_jsonb: bool = False,
|
|
273
288
|
hnsw_kwargs: Optional[Dict[str, Any]] = None,
|
|
274
289
|
create_engine_kwargs: Optional[Dict[str, Any]] = None,
|
|
290
|
+
use_halfvec: bool = False,
|
|
275
291
|
) -> "PGVectorStore":
|
|
276
292
|
"""Construct from params.
|
|
277
293
|
|
|
@@ -296,6 +312,7 @@ class PGVectorStore(BasePydanticVectorStore):
|
|
|
296
312
|
contains "hnsw_ef_construction", "hnsw_ef_search", "hnsw_m", and optionally "hnsw_dist_method". Defaults to None,
|
|
297
313
|
which turns off HNSW search.
|
|
298
314
|
create_engine_kwargs (Optional[Dict[str, Any]], optional): Engine parameters to pass to create_engine. Defaults to None.
|
|
315
|
+
use_halfvec (bool, optional): If `True`, use half-precision vectors. Defaults to False.
|
|
299
316
|
|
|
300
317
|
Returns:
|
|
301
318
|
PGVectorStore: Instance of PGVectorStore constructed from params.
|
|
@@ -321,6 +338,7 @@ class PGVectorStore(BasePydanticVectorStore):
|
|
|
321
338
|
use_jsonb=use_jsonb,
|
|
322
339
|
hnsw_kwargs=hnsw_kwargs,
|
|
323
340
|
create_engine_kwargs=create_engine_kwargs,
|
|
341
|
+
use_halfvec=use_halfvec,
|
|
324
342
|
)
|
|
325
343
|
|
|
326
344
|
@property
|
|
@@ -396,13 +414,25 @@ class PGVectorStore(BasePydanticVectorStore):
|
|
|
396
414
|
|
|
397
415
|
hnsw_ef_construction = self.hnsw_kwargs.pop("hnsw_ef_construction")
|
|
398
416
|
hnsw_m = self.hnsw_kwargs.pop("hnsw_m")
|
|
399
|
-
|
|
417
|
+
|
|
418
|
+
# If user didn’t specify an operator, pick a default based on whether halfvec is used
|
|
419
|
+
if "hnsw_dist_method" in self.hnsw_kwargs:
|
|
420
|
+
hnsw_dist_method = self.hnsw_kwargs.pop("hnsw_dist_method")
|
|
421
|
+
else:
|
|
422
|
+
if self.use_halfvec:
|
|
423
|
+
hnsw_dist_method = "halfvec_l2_ops"
|
|
424
|
+
else:
|
|
425
|
+
# Default to vector_cosine_ops
|
|
426
|
+
hnsw_dist_method = "vector_cosine_ops"
|
|
400
427
|
|
|
401
428
|
index_name = f"{self._table_class.__tablename__}_embedding_idx"
|
|
402
429
|
|
|
403
430
|
with self._session() as session, session.begin():
|
|
404
431
|
statement = sqlalchemy.text(
|
|
405
|
-
f"CREATE INDEX IF NOT EXISTS {index_name}
|
|
432
|
+
f"CREATE INDEX IF NOT EXISTS {index_name} "
|
|
433
|
+
f"ON {self.schema_name}.{self._table_class.__tablename__} "
|
|
434
|
+
f"USING hnsw (embedding {hnsw_dist_method}) "
|
|
435
|
+
f"WITH (m = {hnsw_m}, ef_construction = {hnsw_ef_construction})"
|
|
406
436
|
)
|
|
407
437
|
session.execute(statement)
|
|
408
438
|
session.commit()
|
|
@@ -494,6 +524,8 @@ class PGVectorStore(BasePydanticVectorStore):
|
|
|
494
524
|
return "@>"
|
|
495
525
|
elif operator == FilterOperator.TEXT_MATCH:
|
|
496
526
|
return "LIKE"
|
|
527
|
+
elif operator == FilterOperator.TEXT_MATCH_INSENSITIVE:
|
|
528
|
+
return "ILIKE"
|
|
497
529
|
else:
|
|
498
530
|
_logger.warning(f"Unknown operator: {operator}, fallback to '='")
|
|
499
531
|
return "="
|
|
@@ -520,8 +552,11 @@ class PGVectorStore(BasePydanticVectorStore):
|
|
|
520
552
|
f"{self._to_postgres_operator(filter_.operator)} "
|
|
521
553
|
f"'[\"{filter_.value}\"]'"
|
|
522
554
|
)
|
|
523
|
-
elif
|
|
524
|
-
|
|
555
|
+
elif (
|
|
556
|
+
filter_.operator == FilterOperator.TEXT_MATCH
|
|
557
|
+
or filter_.operator == FilterOperator.TEXT_MATCH_INSENSITIVE
|
|
558
|
+
):
|
|
559
|
+
# Where the operator is text_match or ilike, we need to wrap the filter in '%' characters
|
|
525
560
|
return text(
|
|
526
561
|
f"metadata_->>'{filter_.key}' "
|
|
527
562
|
f"{self._to_postgres_operator(filter_.operator)} "
|
{llama_index_vector_stores_postgres-0.4.0 → llama_index_vector_stores_postgres-0.4.2}/pyproject.toml
RENAMED
|
@@ -27,14 +27,14 @@ exclude = ["**/BUILD"]
|
|
|
27
27
|
license = "MIT"
|
|
28
28
|
name = "llama-index-vector-stores-postgres"
|
|
29
29
|
readme = "README.md"
|
|
30
|
-
version = "0.4.
|
|
30
|
+
version = "0.4.2"
|
|
31
31
|
|
|
32
32
|
[tool.poetry.dependencies]
|
|
33
33
|
python = ">=3.9,<4.0"
|
|
34
34
|
pgvector = ">=0.3.6,<1.0.0"
|
|
35
35
|
psycopg2-binary = ">=2.9.9,<3.0.0"
|
|
36
36
|
asyncpg = ">=0.29.0,<1.0.0"
|
|
37
|
-
llama-index-core = "^0.12.
|
|
37
|
+
llama-index-core = "^0.12.6"
|
|
38
38
|
|
|
39
39
|
[tool.poetry.dependencies.sqlalchemy]
|
|
40
40
|
extras = ["asyncio"]
|
{llama_index_vector_stores_postgres-0.4.0 → llama_index_vector_stores_postgres-0.4.2}/README.md
RENAMED
|
File without changes
|
|
File without changes
|