pgvector-haystack 6.6.1__tar.gz → 8.0.0__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.
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/CHANGELOG.md +19 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/PKG-INFO +3 -3
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/pyproject.toml +2 -2
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/src/haystack_integrations/document_stores/pgvector/document_store.py +19 -10
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/tests/test_document_store.py +7 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/tests/test_document_store_async.py +8 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/.gitignore +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/LICENSE.txt +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/README.md +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/examples/embedding_retrieval.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/examples/hybrid_retrieval.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/pydoc/config_docusaurus.yml +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/src/haystack_integrations/components/retrievers/pgvector/__init__.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/src/haystack_integrations/components/retrievers/pgvector/embedding_retriever.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/src/haystack_integrations/components/retrievers/pgvector/keyword_retriever.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/src/haystack_integrations/components/retrievers/py.typed +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/src/haystack_integrations/document_stores/pgvector/__init__.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/src/haystack_integrations/document_stores/pgvector/converters.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/src/haystack_integrations/document_stores/pgvector/filters.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/src/haystack_integrations/document_stores/py.typed +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/tests/__init__.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/tests/conftest.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/tests/test_converters.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/tests/test_filters.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/tests/test_retrieval.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/tests/test_retrieval_async.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-8.0.0}/tests/test_retrievers.py +0 -0
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [integrations/pgvector-v7.0.0] - 2026-09-29
|
|
4
|
+
|
|
5
|
+
### 🐛 Bug Fixes
|
|
6
|
+
|
|
7
|
+
- [**breaking**] Pgvector - an empty filter must not delete every document (#4006)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## [integrations/pgvector-v6.6.1] - 2026-09-25
|
|
11
|
+
|
|
12
|
+
### 🐛 Bug Fixes
|
|
13
|
+
|
|
14
|
+
- *(pgvector)* Raise FilterError on empty logical conditions (#3946)
|
|
15
|
+
- *(pgvector)* Count every written document in write_documents_async (#3964)
|
|
16
|
+
|
|
17
|
+
### ⚙️ CI
|
|
18
|
+
|
|
19
|
+
- Improve changelog generation; fix existing changelogs (#3883)
|
|
20
|
+
|
|
21
|
+
|
|
3
22
|
## [integrations/pgvector-v6.6.0] - 2026-08-26
|
|
4
23
|
|
|
5
24
|
### 🐛 Bug Fixes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: pgvector-haystack
|
|
3
|
-
Version:
|
|
3
|
+
Version: 8.0.0
|
|
4
4
|
Summary: An integration of pgvector (vector search extension for Postgres) with Haystack
|
|
5
5
|
Project-URL: Source, https://github.com/deepset-ai/haystack-core-integrations
|
|
6
6
|
Project-URL: Documentation, https://github.com/deepset-ai/haystack-core-integrations/blob/main/integrations/pgvector/README.md
|
|
@@ -11,14 +11,14 @@ License-File: LICENSE.txt
|
|
|
11
11
|
Classifier: Development Status :: 4 - Beta
|
|
12
12
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
13
13
|
Classifier: Programming Language :: Python
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
15
14
|
Classifier: Programming Language :: Python :: 3.11
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.13
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
19
19
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
20
20
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
21
|
-
Requires-Python: >=3.
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
22
|
Requires-Dist: haystack-ai>=2.28.0
|
|
23
23
|
Requires-Dist: pgvector>=0.3.0
|
|
24
24
|
Requires-Dist: psycopg[binary]
|
|
@@ -7,7 +7,7 @@ name = "pgvector-haystack"
|
|
|
7
7
|
dynamic = ["version"]
|
|
8
8
|
description = "An integration of pgvector (vector search extension for Postgres) with Haystack"
|
|
9
9
|
readme = "README.md"
|
|
10
|
-
requires-python = ">=3.
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
11
|
license = "Apache-2.0"
|
|
12
12
|
keywords = []
|
|
13
13
|
authors = [{ name = "deepset GmbH", email = "info@deepset.ai" }]
|
|
@@ -15,11 +15,11 @@ classifiers = [
|
|
|
15
15
|
"License :: OSI Approved :: Apache Software License",
|
|
16
16
|
"Development Status :: 4 - Beta",
|
|
17
17
|
"Programming Language :: Python",
|
|
18
|
-
"Programming Language :: Python :: 3.10",
|
|
19
18
|
"Programming Language :: Python :: 3.11",
|
|
20
19
|
"Programming Language :: Python :: 3.12",
|
|
21
20
|
"Programming Language :: Python :: 3.13",
|
|
22
21
|
"Programming Language :: Python :: 3.14",
|
|
22
|
+
"Programming Language :: Python :: 3.15",
|
|
23
23
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
24
24
|
"Programming Language :: Python :: Implementation :: PyPy",
|
|
25
25
|
]
|
|
@@ -9,7 +9,8 @@ from haystack import default_from_dict, default_to_dict, logging
|
|
|
9
9
|
from haystack.dataclasses.document import Document
|
|
10
10
|
from haystack.document_stores.errors import DocumentStoreError, DuplicateDocumentError
|
|
11
11
|
from haystack.document_stores.types import DuplicatePolicy
|
|
12
|
-
from haystack.
|
|
12
|
+
from haystack.errors import FilterError
|
|
13
|
+
from haystack.utils.auth import Secret
|
|
13
14
|
from psycopg import AsyncConnection, Connection, Cursor, Error, IntegrityError
|
|
14
15
|
from psycopg.cursor_async import AsyncCursor
|
|
15
16
|
from psycopg.rows import DictRow, dict_row
|
|
@@ -221,7 +222,6 @@ class PgvectorDocumentStore:
|
|
|
221
222
|
:returns:
|
|
222
223
|
Deserialized component.
|
|
223
224
|
"""
|
|
224
|
-
deserialize_secrets_inplace(data["init_parameters"], ["connection_string"])
|
|
225
225
|
return default_from_dict(cls, data)
|
|
226
226
|
|
|
227
227
|
def close(self) -> None:
|
|
@@ -1078,18 +1078,21 @@ class PgvectorDocumentStore:
|
|
|
1078
1078
|
:param filters: The filters to apply to select documents for deletion.
|
|
1079
1079
|
For filter syntax, see [Haystack metadata filtering](https://docs.haystack.deepset.ai/docs/metadata-filtering)
|
|
1080
1080
|
:returns: The number of documents deleted.
|
|
1081
|
+
:raises FilterError: If `filters` is empty. Use `delete_all_documents()` to delete everything.
|
|
1081
1082
|
"""
|
|
1082
1083
|
_validate_filters(filters)
|
|
1084
|
+
if not filters:
|
|
1085
|
+
# An empty filter would compile to an unqualified DELETE and empty the table
|
|
1086
|
+
msg = "delete_by_filter requires a non-empty filter. Use delete_all_documents() to delete every document."
|
|
1087
|
+
raise FilterError(msg)
|
|
1083
1088
|
|
|
1084
1089
|
delete_sql = SQL("DELETE FROM {schema_name}.{table_name}").format(
|
|
1085
1090
|
schema_name=Identifier(self.schema_name),
|
|
1086
1091
|
table_name=Identifier(self.table_name),
|
|
1087
1092
|
)
|
|
1088
1093
|
|
|
1089
|
-
params = ()
|
|
1090
|
-
|
|
1091
|
-
sql_where_clause, params = _convert_filters_to_where_clause_and_params(filters)
|
|
1092
|
-
delete_sql += sql_where_clause
|
|
1094
|
+
sql_where_clause, params = _convert_filters_to_where_clause_and_params(filters)
|
|
1095
|
+
delete_sql += sql_where_clause
|
|
1093
1096
|
|
|
1094
1097
|
self._ensure_db_setup()
|
|
1095
1098
|
assert self._cursor is not None
|
|
@@ -1120,18 +1123,24 @@ class PgvectorDocumentStore:
|
|
|
1120
1123
|
:param filters: The filters to apply to select documents for deletion.
|
|
1121
1124
|
For filter syntax, see [Haystack metadata filtering](https://docs.haystack.deepset.ai/docs/metadata-filtering)
|
|
1122
1125
|
:returns: The number of documents deleted.
|
|
1126
|
+
:raises FilterError: If `filters` is empty. Use `delete_all_documents_async()` to delete everything.
|
|
1123
1127
|
"""
|
|
1124
1128
|
_validate_filters(filters)
|
|
1129
|
+
if not filters:
|
|
1130
|
+
# An empty filter would compile to an unqualified DELETE and empty the table
|
|
1131
|
+
msg = (
|
|
1132
|
+
"delete_by_filter_async requires a non-empty filter. "
|
|
1133
|
+
"Use delete_all_documents_async() to delete every document."
|
|
1134
|
+
)
|
|
1135
|
+
raise FilterError(msg)
|
|
1125
1136
|
|
|
1126
1137
|
delete_sql = SQL("DELETE FROM {schema_name}.{table_name}").format(
|
|
1127
1138
|
schema_name=Identifier(self.schema_name),
|
|
1128
1139
|
table_name=Identifier(self.table_name),
|
|
1129
1140
|
)
|
|
1130
1141
|
|
|
1131
|
-
params = ()
|
|
1132
|
-
|
|
1133
|
-
sql_where_clause, params = _convert_filters_to_where_clause_and_params(filters)
|
|
1134
|
-
delete_sql += sql_where_clause
|
|
1142
|
+
sql_where_clause, params = _convert_filters_to_where_clause_and_params(filters)
|
|
1143
|
+
delete_sql += sql_where_clause
|
|
1135
1144
|
|
|
1136
1145
|
await self._ensure_db_setup_async()
|
|
1137
1146
|
assert self._async_cursor is not None
|
|
@@ -9,6 +9,7 @@ import pytest
|
|
|
9
9
|
from haystack.dataclasses.document import ByteStream, Document
|
|
10
10
|
from haystack.document_stores.errors import DocumentStoreError, DuplicateDocumentError
|
|
11
11
|
from haystack.document_stores.types import DuplicatePolicy
|
|
12
|
+
from haystack.errors import FilterError
|
|
12
13
|
from haystack.testing.document_store import (
|
|
13
14
|
CountDocumentsByFilterTest,
|
|
14
15
|
CountDocumentsTest,
|
|
@@ -165,6 +166,12 @@ class TestDocumentStore(
|
|
|
165
166
|
assert document_store._connection is not None
|
|
166
167
|
|
|
167
168
|
|
|
169
|
+
def test_delete_by_filter_rejects_an_empty_filter(mock_store):
|
|
170
|
+
"""An empty filter would compile to an unqualified DELETE and empty the table."""
|
|
171
|
+
with pytest.raises(FilterError, match="non-empty filter"):
|
|
172
|
+
mock_store.delete_by_filter({})
|
|
173
|
+
|
|
174
|
+
|
|
168
175
|
@pytest.mark.usefixtures("patches_for_unit_tests")
|
|
169
176
|
def test_init(monkeypatch):
|
|
170
177
|
monkeypatch.setenv("PG_CONN_STR", "some_connection_string")
|
|
@@ -9,6 +9,7 @@ import pytest
|
|
|
9
9
|
from haystack.dataclasses.document import ByteStream, Document
|
|
10
10
|
from haystack.document_stores.errors import DocumentStoreError, DuplicateDocumentError
|
|
11
11
|
from haystack.document_stores.types import DuplicatePolicy
|
|
12
|
+
from haystack.errors import FilterError
|
|
12
13
|
from haystack.testing.document_store_async import (
|
|
13
14
|
CountDocumentsAsyncTest,
|
|
14
15
|
CountDocumentsByFilterAsyncTest,
|
|
@@ -367,6 +368,13 @@ async def test_write_documents_async_rejects_non_document_items(mock_store):
|
|
|
367
368
|
await mock_store.write_documents_async([{"not": "a document"}])
|
|
368
369
|
|
|
369
370
|
|
|
371
|
+
@pytest.mark.asyncio
|
|
372
|
+
async def test_delete_by_filter_async_rejects_an_empty_filter(mock_store):
|
|
373
|
+
"""Same contract as the sync path, and the message must name the async methods."""
|
|
374
|
+
with pytest.raises(FilterError, match=r"delete_by_filter_async requires .* delete_all_documents_async\(\)"):
|
|
375
|
+
await mock_store.delete_by_filter_async({})
|
|
376
|
+
|
|
377
|
+
|
|
370
378
|
@pytest.mark.asyncio
|
|
371
379
|
async def test_count_unique_metadata_by_filter_async_rejects_empty_fields(mock_store):
|
|
372
380
|
with pytest.raises(ValueError, match="metadata_fields must be a non-empty list"):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|