pgvector-haystack 6.6.1__tar.gz → 7.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-7.0.0}/CHANGELOG.md +12 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/PKG-INFO +1 -1
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/src/haystack_integrations/document_stores/pgvector/document_store.py +18 -8
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/tests/test_document_store.py +7 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/tests/test_document_store_async.py +8 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/.gitignore +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/LICENSE.txt +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/README.md +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/examples/embedding_retrieval.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/examples/hybrid_retrieval.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/pydoc/config_docusaurus.yml +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/pyproject.toml +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/src/haystack_integrations/components/retrievers/pgvector/__init__.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/src/haystack_integrations/components/retrievers/pgvector/embedding_retriever.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/src/haystack_integrations/components/retrievers/pgvector/keyword_retriever.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/src/haystack_integrations/components/retrievers/py.typed +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/src/haystack_integrations/document_stores/pgvector/__init__.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/src/haystack_integrations/document_stores/pgvector/converters.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/src/haystack_integrations/document_stores/pgvector/filters.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/src/haystack_integrations/document_stores/py.typed +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/tests/__init__.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/tests/conftest.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/tests/test_converters.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/tests/test_filters.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/tests/test_retrieval.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/tests/test_retrieval_async.py +0 -0
- {pgvector_haystack-6.6.1 → pgvector_haystack-7.0.0}/tests/test_retrievers.py +0 -0
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [integrations/pgvector-v6.6.1] - 2026-09-25
|
|
4
|
+
|
|
5
|
+
### 🐛 Bug Fixes
|
|
6
|
+
|
|
7
|
+
- *(pgvector)* Raise FilterError on empty logical conditions (#3946)
|
|
8
|
+
- *(pgvector)* Count every written document in write_documents_async (#3964)
|
|
9
|
+
|
|
10
|
+
### ⚙️ CI
|
|
11
|
+
|
|
12
|
+
- Improve changelog generation; fix existing changelogs (#3883)
|
|
13
|
+
|
|
14
|
+
|
|
3
15
|
## [integrations/pgvector-v6.6.0] - 2026-08-26
|
|
4
16
|
|
|
5
17
|
### 🐛 Bug Fixes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: pgvector-haystack
|
|
3
|
-
Version:
|
|
3
|
+
Version: 7.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
|
|
@@ -9,6 +9,7 @@ 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.errors import FilterError
|
|
12
13
|
from haystack.utils.auth import Secret, deserialize_secrets_inplace
|
|
13
14
|
from psycopg import AsyncConnection, Connection, Cursor, Error, IntegrityError
|
|
14
15
|
from psycopg.cursor_async import AsyncCursor
|
|
@@ -1078,18 +1079,21 @@ class PgvectorDocumentStore:
|
|
|
1078
1079
|
:param filters: The filters to apply to select documents for deletion.
|
|
1079
1080
|
For filter syntax, see [Haystack metadata filtering](https://docs.haystack.deepset.ai/docs/metadata-filtering)
|
|
1080
1081
|
:returns: The number of documents deleted.
|
|
1082
|
+
:raises FilterError: If `filters` is empty. Use `delete_all_documents()` to delete everything.
|
|
1081
1083
|
"""
|
|
1082
1084
|
_validate_filters(filters)
|
|
1085
|
+
if not filters:
|
|
1086
|
+
# An empty filter would compile to an unqualified DELETE and empty the table
|
|
1087
|
+
msg = "delete_by_filter requires a non-empty filter. Use delete_all_documents() to delete every document."
|
|
1088
|
+
raise FilterError(msg)
|
|
1083
1089
|
|
|
1084
1090
|
delete_sql = SQL("DELETE FROM {schema_name}.{table_name}").format(
|
|
1085
1091
|
schema_name=Identifier(self.schema_name),
|
|
1086
1092
|
table_name=Identifier(self.table_name),
|
|
1087
1093
|
)
|
|
1088
1094
|
|
|
1089
|
-
params = ()
|
|
1090
|
-
|
|
1091
|
-
sql_where_clause, params = _convert_filters_to_where_clause_and_params(filters)
|
|
1092
|
-
delete_sql += sql_where_clause
|
|
1095
|
+
sql_where_clause, params = _convert_filters_to_where_clause_and_params(filters)
|
|
1096
|
+
delete_sql += sql_where_clause
|
|
1093
1097
|
|
|
1094
1098
|
self._ensure_db_setup()
|
|
1095
1099
|
assert self._cursor is not None
|
|
@@ -1120,18 +1124,24 @@ class PgvectorDocumentStore:
|
|
|
1120
1124
|
:param filters: The filters to apply to select documents for deletion.
|
|
1121
1125
|
For filter syntax, see [Haystack metadata filtering](https://docs.haystack.deepset.ai/docs/metadata-filtering)
|
|
1122
1126
|
:returns: The number of documents deleted.
|
|
1127
|
+
:raises FilterError: If `filters` is empty. Use `delete_all_documents_async()` to delete everything.
|
|
1123
1128
|
"""
|
|
1124
1129
|
_validate_filters(filters)
|
|
1130
|
+
if not filters:
|
|
1131
|
+
# An empty filter would compile to an unqualified DELETE and empty the table
|
|
1132
|
+
msg = (
|
|
1133
|
+
"delete_by_filter_async requires a non-empty filter. "
|
|
1134
|
+
"Use delete_all_documents_async() to delete every document."
|
|
1135
|
+
)
|
|
1136
|
+
raise FilterError(msg)
|
|
1125
1137
|
|
|
1126
1138
|
delete_sql = SQL("DELETE FROM {schema_name}.{table_name}").format(
|
|
1127
1139
|
schema_name=Identifier(self.schema_name),
|
|
1128
1140
|
table_name=Identifier(self.table_name),
|
|
1129
1141
|
)
|
|
1130
1142
|
|
|
1131
|
-
params = ()
|
|
1132
|
-
|
|
1133
|
-
sql_where_clause, params = _convert_filters_to_where_clause_and_params(filters)
|
|
1134
|
-
delete_sql += sql_where_clause
|
|
1143
|
+
sql_where_clause, params = _convert_filters_to_where_clause_and_params(filters)
|
|
1144
|
+
delete_sql += sql_where_clause
|
|
1135
1145
|
|
|
1136
1146
|
await self._ensure_db_setup_async()
|
|
1137
1147
|
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
|
|
File without changes
|