pgvector-haystack 1.1.0__tar.gz → 1.2.1__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.
Files changed (23) hide show
  1. pgvector_haystack-1.2.1/CHANGELOG.md +103 -0
  2. {pgvector_haystack-1.1.0 → pgvector_haystack-1.2.1}/PKG-INFO +5 -4
  3. {pgvector_haystack-1.1.0 → pgvector_haystack-1.2.1}/README.md +1 -1
  4. {pgvector_haystack-1.1.0 → pgvector_haystack-1.2.1}/src/haystack_integrations/document_stores/pgvector/document_store.py +12 -2
  5. {pgvector_haystack-1.1.0 → pgvector_haystack-1.2.1}/tests/test_document_store.py +49 -0
  6. {pgvector_haystack-1.1.0 → pgvector_haystack-1.2.1}/tests/test_retrievers.py +6 -0
  7. pgvector_haystack-1.1.0/CHANGELOG.md +0 -56
  8. {pgvector_haystack-1.1.0 → pgvector_haystack-1.2.1}/.gitignore +0 -0
  9. {pgvector_haystack-1.1.0 → pgvector_haystack-1.2.1}/LICENSE.txt +0 -0
  10. {pgvector_haystack-1.1.0 → pgvector_haystack-1.2.1}/examples/embedding_retrieval.py +0 -0
  11. {pgvector_haystack-1.1.0 → pgvector_haystack-1.2.1}/examples/hybrid_retrieval.py +0 -0
  12. {pgvector_haystack-1.1.0 → pgvector_haystack-1.2.1}/pydoc/config.yml +0 -0
  13. {pgvector_haystack-1.1.0 → pgvector_haystack-1.2.1}/pyproject.toml +0 -0
  14. {pgvector_haystack-1.1.0 → pgvector_haystack-1.2.1}/src/haystack_integrations/components/retrievers/pgvector/__init__.py +0 -0
  15. {pgvector_haystack-1.1.0 → pgvector_haystack-1.2.1}/src/haystack_integrations/components/retrievers/pgvector/embedding_retriever.py +0 -0
  16. {pgvector_haystack-1.1.0 → pgvector_haystack-1.2.1}/src/haystack_integrations/components/retrievers/pgvector/keyword_retriever.py +0 -0
  17. {pgvector_haystack-1.1.0 → pgvector_haystack-1.2.1}/src/haystack_integrations/document_stores/pgvector/__init__.py +0 -0
  18. {pgvector_haystack-1.1.0 → pgvector_haystack-1.2.1}/src/haystack_integrations/document_stores/pgvector/filters.py +0 -0
  19. {pgvector_haystack-1.1.0 → pgvector_haystack-1.2.1}/tests/__init__.py +0 -0
  20. {pgvector_haystack-1.1.0 → pgvector_haystack-1.2.1}/tests/conftest.py +0 -0
  21. {pgvector_haystack-1.1.0 → pgvector_haystack-1.2.1}/tests/test_embedding_retrieval.py +0 -0
  22. {pgvector_haystack-1.1.0 → pgvector_haystack-1.2.1}/tests/test_filters.py +0 -0
  23. {pgvector_haystack-1.1.0 → pgvector_haystack-1.2.1}/tests/test_keyword_retrieval.py +0 -0
@@ -0,0 +1,103 @@
1
+ # Changelog
2
+
3
+ ## [integrations/pgvector-v1.2.0] - 2024-11-22
4
+
5
+ ### 🚀 Features
6
+
7
+ - Add `create_extension` parameter to control vector extension creation (#1213)
8
+
9
+
10
+ ## [integrations/pgvector-v1.1.0] - 2024-11-21
11
+
12
+ ### 🚀 Features
13
+
14
+ - Add filter_policy to pgvector integration (#820)
15
+ - Add schema support to pgvector document store. (#1095)
16
+ - Pgvector - recreate the connection if it is no longer valid (#1202)
17
+
18
+ ### 🐛 Bug Fixes
19
+
20
+ - `PgVector` - Fallback to default filter policy when deserializing retrievers without the init parameter (#900)
21
+
22
+ ### 📚 Documentation
23
+
24
+ - Explain different connection string formats in the docstring (#1132)
25
+
26
+ ### 🧪 Testing
27
+
28
+ - Do not retry tests in `hatch run test` command (#954)
29
+
30
+ ### ⚙️ CI
31
+
32
+ - Retry tests to reduce flakyness (#836)
33
+ - Adopt uv as installer (#1142)
34
+
35
+ ### 🧹 Chores
36
+
37
+ - Update ruff invocation to include check parameter (#853)
38
+ - PgVector - remove legacy filter support (#1068)
39
+ - Update changelog after removing legacy filters (#1083)
40
+ - Update ruff linting scripts and settings (#1105)
41
+
42
+ ### 🌀 Miscellaneous
43
+
44
+ - Ci: install `pytest-rerunfailures` where needed; add retry config to `test-cov` script (#845)
45
+ - Chore: Minor retriever pydoc fix (#884)
46
+ - Chore: Update pgvector test for the new `apply_filter_policy` usage (#970)
47
+ - Chore: pgvector ruff update, don't ruff tests (#984)
48
+
49
+ ## [integrations/pgvector-v0.4.0] - 2024-06-20
50
+
51
+ ### 🚀 Features
52
+
53
+ - Defer the database connection to when it's needed (#773)
54
+ - Add customizable index names for pgvector (#818)
55
+
56
+ ### 🌀 Miscellaneous
57
+
58
+ - Docs: add missing api references (#728)
59
+ - [deepset-ai/haystack-core-integrations#727] (#738)
60
+
61
+ ## [integrations/pgvector-v0.2.0] - 2024-05-08
62
+
63
+ ### 🚀 Features
64
+
65
+ - `MongoDBAtlasEmbeddingRetriever` (#427)
66
+ - Implement keyword retrieval for pgvector integration (#644)
67
+
68
+ ### 🐛 Bug Fixes
69
+
70
+ - Fix order of API docs (#447)
71
+
72
+ ### 📚 Documentation
73
+
74
+ - Update category slug (#442)
75
+ - Disable-class-def (#556)
76
+
77
+ ### 🌀 Miscellaneous
78
+
79
+ - Pgvector - review docstrings and API reference (#502)
80
+ - Refactor tests (#574)
81
+ - Remove references to Python 3.7 (#601)
82
+ - Make Document Stores initially skip `SparseEmbedding` (#606)
83
+ - Chore: add license classifiers (#680)
84
+ - Type hints in pgvector document store updated for 3.8 compability (#704)
85
+ - Chore: change the pydoc renderer class (#718)
86
+
87
+ ## [integrations/pgvector-v0.1.0] - 2024-02-14
88
+
89
+ ### 🐛 Bug Fixes
90
+
91
+ - Pgvector: fix linting (#328)
92
+
93
+ ### 🌀 Miscellaneous
94
+
95
+ - Pgvector Document Store - minimal implementation (#239)
96
+ - Pgvector - filters (#257)
97
+ - Pgvector - embedding retrieval (#298)
98
+ - Pgvector - Embedding Retriever (#320)
99
+ - Pgvector: generate API docs (#325)
100
+ - Pgvector: add an example (#334)
101
+ - Adopt `Secret` to pgvector (#402)
102
+
103
+ <!-- generated by git-cliff -->
@@ -1,12 +1,13 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: pgvector-haystack
3
- Version: 1.1.0
3
+ Version: 1.2.1
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
7
7
  Project-URL: Issues, https://github.com/deepset-ai/haystack-core-integrations/issues
8
8
  Author-email: deepset GmbH <info@deepset.ai>
9
- License: Apache-2.0
9
+ License-Expression: Apache-2.0
10
+ License-File: LICENSE.txt
10
11
  Classifier: Development Status :: 4 - Beta
11
12
  Classifier: License :: OSI Approved :: Apache Software License
12
13
  Classifier: Programming Language :: Python
@@ -47,7 +48,7 @@ pip install pgvector-haystack
47
48
 
48
49
  Ensure that you have a PostgreSQL running with the `pgvector` extension. For a quick setup using Docker, run:
49
50
  ```
50
- docker run -d -p 5432:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=postgres ankane/pgvector
51
+ docker run -d -p 5432:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=postgres pgvector/pgvector:pg17
51
52
  ```
52
53
 
53
54
  then run the tests:
@@ -22,7 +22,7 @@ pip install pgvector-haystack
22
22
 
23
23
  Ensure that you have a PostgreSQL running with the `pgvector` extension. For a quick setup using Docker, run:
24
24
  ```
25
- docker run -d -p 5432:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=postgres ankane/pgvector
25
+ docker run -d -p 5432:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=postgres pgvector/pgvector:pg17
26
26
  ```
27
27
 
28
28
  then run the tests:
@@ -78,6 +78,7 @@ class PgvectorDocumentStore:
78
78
  self,
79
79
  *,
80
80
  connection_string: Secret = Secret.from_env_var("PG_CONN_STR"),
81
+ create_extension: bool = True,
81
82
  schema_name: str = "public",
82
83
  table_name: str = "haystack_documents",
83
84
  language: str = "english",
@@ -102,6 +103,10 @@ class PgvectorDocumentStore:
102
103
  e.g.: `PG_CONN_STR="host=HOST port=PORT dbname=DBNAME user=USER password=PASSWORD"`
103
104
  See [PostgreSQL Documentation](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING)
104
105
  for more details.
106
+ :param create_extension: Whether to create the pgvector extension if it doesn't exist.
107
+ Set this to `True` (default) to automatically create the extension if it is missing.
108
+ Creating the extension may require superuser privileges.
109
+ If set to `False`, ensure the extension is already installed; otherwise, an error will be raised.
105
110
  :param schema_name: The name of the schema the table is created in. The schema must already exist.
106
111
  :param table_name: The name of the table to use to store Haystack documents.
107
112
  :param language: The language to be used to parse query and document content in keyword retrieval.
@@ -138,6 +143,7 @@ class PgvectorDocumentStore:
138
143
  """
139
144
 
140
145
  self.connection_string = connection_string
146
+ self.create_extension = create_extension
141
147
  self.table_name = table_name
142
148
  self.schema_name = schema_name
143
149
  self.embedding_dimension = embedding_dimension
@@ -194,7 +200,8 @@ class PgvectorDocumentStore:
194
200
  conn_str = self.connection_string.resolve_value() or ""
195
201
  connection = connect(conn_str)
196
202
  connection.autocommit = True
197
- connection.execute("CREATE EXTENSION IF NOT EXISTS vector")
203
+ if self.create_extension:
204
+ connection.execute("CREATE EXTENSION IF NOT EXISTS vector")
198
205
  register_vector(connection) # Note: this must be called before creating the cursors.
199
206
 
200
207
  self._connection = connection
@@ -246,6 +253,7 @@ class PgvectorDocumentStore:
246
253
  return default_to_dict(
247
254
  self,
248
255
  connection_string=self.connection_string.to_dict(),
256
+ create_extension=self.create_extension,
249
257
  schema_name=self.schema_name,
250
258
  table_name=self.table_name,
251
259
  embedding_dimension=self.embedding_dimension,
@@ -381,7 +389,9 @@ class PgvectorDocumentStore:
381
389
  )
382
390
  return
383
391
 
384
- sql_drop_index = SQL("DROP INDEX IF EXISTS {index_name}").format(index_name=Identifier(self.hnsw_index_name))
392
+ sql_drop_index = SQL("DROP INDEX IF EXISTS {schema_name}.{index_name}").format(
393
+ schema_name=Identifier(self.schema_name), index_name=Identifier(self.hnsw_index_name)
394
+ )
385
395
  self._execute_sql(sql_drop_index, error_msg="Could not drop HNSW index")
386
396
 
387
397
  self._create_hnsw_index()
@@ -5,6 +5,7 @@
5
5
  from unittest.mock import patch
6
6
 
7
7
  import numpy as np
8
+ import psycopg
8
9
  import pytest
9
10
  from haystack.dataclasses.document import ByteStream, Document
10
11
  from haystack.document_stores.errors import DuplicateDocumentError
@@ -66,6 +67,7 @@ def test_init(monkeypatch):
66
67
  monkeypatch.setenv("PG_CONN_STR", "some_connection_string")
67
68
 
68
69
  document_store = PgvectorDocumentStore(
70
+ create_extension=True,
69
71
  schema_name="my_schema",
70
72
  table_name="my_table",
71
73
  embedding_dimension=512,
@@ -79,6 +81,7 @@ def test_init(monkeypatch):
79
81
  keyword_index_name="my_keyword_index",
80
82
  )
81
83
 
84
+ assert document_store.create_extension
82
85
  assert document_store.schema_name == "my_schema"
83
86
  assert document_store.table_name == "my_table"
84
87
  assert document_store.embedding_dimension == 512
@@ -97,6 +100,7 @@ def test_to_dict(monkeypatch):
97
100
  monkeypatch.setenv("PG_CONN_STR", "some_connection_string")
98
101
 
99
102
  document_store = PgvectorDocumentStore(
103
+ create_extension=False,
100
104
  table_name="my_table",
101
105
  embedding_dimension=512,
102
106
  vector_function="l2_distance",
@@ -113,6 +117,7 @@ def test_to_dict(monkeypatch):
113
117
  "type": "haystack_integrations.document_stores.pgvector.document_store.PgvectorDocumentStore",
114
118
  "init_parameters": {
115
119
  "connection_string": {"env_vars": ["PG_CONN_STR"], "strict": True, "type": "env_var"},
120
+ "create_extension": False,
116
121
  "table_name": "my_table",
117
122
  "schema_name": "public",
118
123
  "embedding_dimension": 512,
@@ -255,3 +260,47 @@ def test_from_pg_to_haystack_documents():
255
260
  assert haystack_docs[2].meta == {"meta_key": "meta_value"}
256
261
  assert haystack_docs[2].embedding == [0.7, 0.8, 0.9]
257
262
  assert haystack_docs[2].score is None
263
+
264
+
265
+ @pytest.mark.integration
266
+ def test_hnsw_index_recreation():
267
+ def get_index_oid(document_store, schema_name, index_name):
268
+ sql_get_index_oid = """
269
+ SELECT c.oid
270
+ FROM pg_class c
271
+ JOIN pg_namespace n ON n.oid = c.relnamespace
272
+ WHERE c.relkind = 'i'
273
+ AND n.nspname = %s
274
+ AND c.relname = %s;
275
+ """
276
+ return document_store.cursor.execute(sql_get_index_oid, (schema_name, index_name)).fetchone()[0]
277
+
278
+ # create a new schema
279
+ connection_string = "postgresql://postgres:postgres@localhost:5432/postgres"
280
+ schema_name = "test_schema"
281
+ with psycopg.connect(connection_string, autocommit=True) as conn:
282
+ conn.execute(f"CREATE SCHEMA IF NOT EXISTS {schema_name}")
283
+
284
+ # create a first document store and trigger the creation of the hnsw index
285
+ params = {
286
+ "connection_string": Secret.from_token(connection_string),
287
+ "schema_name": schema_name,
288
+ "table_name": "haystack_test_hnsw_index_recreation",
289
+ "search_strategy": "hnsw",
290
+ }
291
+ ds1 = PgvectorDocumentStore(**params)
292
+ ds1._initialize_table()
293
+
294
+ # get the hnsw index oid
295
+ hnws_index_name = "haystack_hnsw_index"
296
+ first_oid = get_index_oid(ds1, ds1.schema_name, hnws_index_name)
297
+
298
+ # create second document store with recreation enabled
299
+ ds2 = PgvectorDocumentStore(**params, hnsw_recreate_index_if_exists=True)
300
+ ds2._initialize_table()
301
+
302
+ # get the index oid
303
+ second_oid = get_index_oid(ds2, ds2.schema_name, hnws_index_name)
304
+
305
+ # verify that oids differ
306
+ assert second_oid != first_oid, "Index was not recreated (OID remained the same)"
@@ -50,6 +50,7 @@ class TestEmbeddingRetriever:
50
50
  "type": "haystack_integrations.document_stores.pgvector.document_store.PgvectorDocumentStore",
51
51
  "init_parameters": {
52
52
  "connection_string": {"env_vars": ["PG_CONN_STR"], "strict": True, "type": "env_var"},
53
+ "create_extension": True,
53
54
  "schema_name": "public",
54
55
  "table_name": "haystack",
55
56
  "embedding_dimension": 768,
@@ -82,6 +83,7 @@ class TestEmbeddingRetriever:
82
83
  "type": "haystack_integrations.document_stores.pgvector.document_store.PgvectorDocumentStore",
83
84
  "init_parameters": {
84
85
  "connection_string": {"env_vars": ["PG_CONN_STR"], "strict": True, "type": "env_var"},
86
+ "create_extension": False,
85
87
  "table_name": "haystack_test_to_dict",
86
88
  "embedding_dimension": 768,
87
89
  "vector_function": "cosine_similarity",
@@ -106,6 +108,7 @@ class TestEmbeddingRetriever:
106
108
 
107
109
  assert isinstance(document_store, PgvectorDocumentStore)
108
110
  assert isinstance(document_store.connection_string, EnvVarSecret)
111
+ assert not document_store.create_extension
109
112
  assert document_store.table_name == "haystack_test_to_dict"
110
113
  assert document_store.embedding_dimension == 768
111
114
  assert document_store.vector_function == "cosine_similarity"
@@ -176,6 +179,7 @@ class TestKeywordRetriever:
176
179
  "type": "haystack_integrations.document_stores.pgvector.document_store.PgvectorDocumentStore",
177
180
  "init_parameters": {
178
181
  "connection_string": {"env_vars": ["PG_CONN_STR"], "strict": True, "type": "env_var"},
182
+ "create_extension": True,
179
183
  "schema_name": "public",
180
184
  "table_name": "haystack",
181
185
  "embedding_dimension": 768,
@@ -207,6 +211,7 @@ class TestKeywordRetriever:
207
211
  "type": "haystack_integrations.document_stores.pgvector.document_store.PgvectorDocumentStore",
208
212
  "init_parameters": {
209
213
  "connection_string": {"env_vars": ["PG_CONN_STR"], "strict": True, "type": "env_var"},
214
+ "create_extension": False,
210
215
  "table_name": "haystack_test_to_dict",
211
216
  "embedding_dimension": 768,
212
217
  "vector_function": "cosine_similarity",
@@ -230,6 +235,7 @@ class TestKeywordRetriever:
230
235
 
231
236
  assert isinstance(document_store, PgvectorDocumentStore)
232
237
  assert isinstance(document_store.connection_string, EnvVarSecret)
238
+ assert not document_store.create_extension
233
239
  assert document_store.table_name == "haystack_test_to_dict"
234
240
  assert document_store.embedding_dimension == 768
235
241
  assert document_store.vector_function == "cosine_similarity"
@@ -1,56 +0,0 @@
1
- # Changelog
2
-
3
- ## [integrations/pgvector-v1.0.0] - 2024-09-12
4
-
5
- ### 🚀 Features
6
-
7
- - Add filter_policy to pgvector integration (#820)
8
-
9
- ### 🐛 Bug Fixes
10
-
11
- - `PgVector` - Fallback to default filter policy when deserializing retrievers without the init parameter (#900)
12
-
13
- ### 🧪 Testing
14
-
15
- - Do not retry tests in `hatch run test` command (#954)
16
-
17
- ### ⚙️ Miscellaneous Tasks
18
-
19
- - Retry tests to reduce flakyness (#836)
20
- - Update ruff invocation to include check parameter (#853)
21
- - PgVector - remove legacy filter support (#1068)
22
-
23
- ## [integrations/pgvector-v0.4.0] - 2024-06-20
24
-
25
- ### 🚀 Features
26
-
27
- - Defer the database connection to when it's needed (#773)
28
- - Add customizable index names for pgvector (#818)
29
-
30
- ## [integrations/pgvector-v0.2.0] - 2024-05-08
31
-
32
- ### 🚀 Features
33
-
34
- - `MongoDBAtlasEmbeddingRetriever` (#427)
35
- - Implement keyword retrieval for pgvector integration (#644)
36
-
37
- ### 🐛 Bug Fixes
38
-
39
- - Fix order of API docs (#447)
40
-
41
- This PR will also push the docs to Readme
42
-
43
- ### 📚 Documentation
44
-
45
- - Update category slug (#442)
46
- - Disable-class-def (#556)
47
-
48
- ## [integrations/pgvector-v0.1.0] - 2024-02-14
49
-
50
- ### 🐛 Bug Fixes
51
-
52
- - Fix linting (#328)
53
-
54
-
55
-
56
- <!-- generated by git-cliff -->