langchain-google-cloud-sql-pg 0.14.1__tar.gz → 0.16.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.
Files changed (46) hide show
  1. {langchain_google_cloud_sql_pg-0.14.1/src/langchain_google_cloud_sql_pg.egg-info → langchain_google_cloud_sql_pg-0.16.0}/PKG-INFO +33 -16
  2. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/README.rst +21 -1
  3. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/pyproject.toml +12 -15
  4. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/src/langchain_google_cloud_sql_pg/__init__.py +11 -1
  5. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/src/langchain_google_cloud_sql_pg/async_chat_message_history.py +1 -1
  6. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/src/langchain_google_cloud_sql_pg/async_checkpoint.py +5 -3
  7. langchain_google_cloud_sql_pg-0.16.0/src/langchain_google_cloud_sql_pg/async_vectorstore.py +25 -0
  8. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/src/langchain_google_cloud_sql_pg/engine.py +18 -247
  9. langchain_google_cloud_sql_pg-0.16.0/src/langchain_google_cloud_sql_pg/indexes.py +27 -0
  10. langchain_google_cloud_sql_pg-0.16.0/src/langchain_google_cloud_sql_pg/vectorstore.py +167 -0
  11. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/src/langchain_google_cloud_sql_pg/version.py +1 -1
  12. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0/src/langchain_google_cloud_sql_pg.egg-info}/PKG-INFO +33 -16
  13. langchain_google_cloud_sql_pg-0.16.0/src/langchain_google_cloud_sql_pg.egg-info/requires.txt +21 -0
  14. langchain_google_cloud_sql_pg-0.16.0/tests/test_async_chatmessagehistory.py +169 -0
  15. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/tests/test_async_checkpoint.py +111 -42
  16. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/tests/test_async_loader.py +279 -188
  17. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/tests/test_async_vectorstore.py +187 -118
  18. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/tests/test_async_vectorstore_from_methods.py +106 -67
  19. langchain_google_cloud_sql_pg-0.16.0/tests/test_async_vectorstore_index.py +267 -0
  20. langchain_google_cloud_sql_pg-0.16.0/tests/test_async_vectorstore_search.py +852 -0
  21. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/tests/test_checkpoint.py +2 -0
  22. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/tests/test_engine.py +144 -36
  23. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/tests/test_standard_test_suite.py +2 -2
  24. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/tests/test_vectorstore.py +2 -2
  25. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/tests/test_vectorstore_from_methods.py +2 -4
  26. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/tests/test_vectorstore_index.py +4 -4
  27. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/tests/test_vectorstore_search.py +72 -12
  28. langchain_google_cloud_sql_pg-0.14.1/src/langchain_google_cloud_sql_pg/async_vectorstore.py +0 -1201
  29. langchain_google_cloud_sql_pg-0.14.1/src/langchain_google_cloud_sql_pg/indexes.py +0 -105
  30. langchain_google_cloud_sql_pg-0.14.1/src/langchain_google_cloud_sql_pg/vectorstore.py +0 -823
  31. langchain_google_cloud_sql_pg-0.14.1/src/langchain_google_cloud_sql_pg.egg-info/requires.txt +0 -26
  32. langchain_google_cloud_sql_pg-0.14.1/tests/test_async_chatmessagehistory.py +0 -123
  33. langchain_google_cloud_sql_pg-0.14.1/tests/test_async_vectorstore_index.py +0 -143
  34. langchain_google_cloud_sql_pg-0.14.1/tests/test_async_vectorstore_search.py +0 -343
  35. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/LICENSE +0 -0
  36. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/setup.cfg +0 -0
  37. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/src/langchain_google_cloud_sql_pg/async_loader.py +0 -0
  38. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/src/langchain_google_cloud_sql_pg/chat_message_history.py +0 -0
  39. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/src/langchain_google_cloud_sql_pg/checkpoint.py +0 -0
  40. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/src/langchain_google_cloud_sql_pg/loader.py +0 -0
  41. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/src/langchain_google_cloud_sql_pg/py.typed +0 -0
  42. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/src/langchain_google_cloud_sql_pg.egg-info/SOURCES.txt +0 -0
  43. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/src/langchain_google_cloud_sql_pg.egg-info/dependency_links.txt +0 -0
  44. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/src/langchain_google_cloud_sql_pg.egg-info/top_level.txt +0 -0
  45. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/tests/test_chatmessagehistory.py +0 -0
  46. {langchain_google_cloud_sql_pg-0.14.1 → langchain_google_cloud_sql_pg-0.16.0}/tests/test_loader.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langchain-google-cloud-sql-pg
3
- Version: 0.14.1
3
+ Version: 0.16.0
4
4
  Summary: LangChain integrations for Google Cloud SQL for PostgreSQL
5
5
  Author-email: Google LLC <googleapis-packages@google.com>
6
6
  License:
@@ -214,31 +214,28 @@ Classifier: Intended Audience :: Developers
214
214
  Classifier: License :: OSI Approved :: Apache Software License
215
215
  Classifier: Programming Language :: Python
216
216
  Classifier: Programming Language :: Python :: 3
217
- Classifier: Programming Language :: Python :: 3.9
218
217
  Classifier: Programming Language :: Python :: 3.10
219
218
  Classifier: Programming Language :: Python :: 3.11
220
219
  Classifier: Programming Language :: Python :: 3.12
221
- Requires-Python: >=3.9
220
+ Classifier: Programming Language :: Python :: 3.13
221
+ Requires-Python: >=3.10
222
222
  Description-Content-Type: text/x-rst
223
223
  License-File: LICENSE
224
224
  Requires-Dist: cloud-sql-python-connector[asyncpg]<2.0.0,>=1.10.0
225
- Requires-Dist: langchain-core<1.0.0,>=0.2.36
226
225
  Requires-Dist: numpy<3.0.0,>=1.24.4; python_version >= "3.11"
227
226
  Requires-Dist: numpy<=2.2.6,>=1.24.4; python_version == "3.10"
228
- Requires-Dist: numpy<=2.0.2,>=1.24.4; python_version <= "3.9"
229
- Requires-Dist: pgvector<1.0.0,>=0.2.5
230
- Requires-Dist: SQLAlchemy[asyncio]<3.0.0,>=2.0.25
227
+ Requires-Dist: langchain-postgres>=0.0.16
231
228
  Provides-Extra: langgraph
232
- Requires-Dist: langgraph-checkpoint<3.0.0,>=2.0.9; extra == "langgraph"
229
+ Requires-Dist: langgraph-checkpoint<5.0.0,>=4.0.0; extra == "langgraph"
233
230
  Provides-Extra: test
234
- Requires-Dist: black[jupyter]==25.1.0; extra == "test"
235
- Requires-Dist: isort==6.0.1; extra == "test"
236
- Requires-Dist: mypy==1.15.0; extra == "test"
231
+ Requires-Dist: black[jupyter]==26.3.1; extra == "test"
232
+ Requires-Dist: isort==9.0.2; extra == "test"
233
+ Requires-Dist: mypy==1.19.1; extra == "test"
237
234
  Requires-Dist: pytest-asyncio==0.26.0; extra == "test"
238
- Requires-Dist: pytest==8.4.1; extra == "test"
239
- Requires-Dist: pytest-cov==6.2.1; extra == "test"
240
- Requires-Dist: langchain-tests==0.3.20; extra == "test"
241
- Requires-Dist: langgraph==0.5.2; extra == "test"
235
+ Requires-Dist: pytest==8.4.2; extra == "test"
236
+ Requires-Dist: pytest-cov==7.0.0; extra == "test"
237
+ Requires-Dist: langchain-tests==1.1.2; extra == "test"
238
+ Requires-Dist: langgraph>=1.2.2; extra == "test"
242
239
  Dynamic: license-file
243
240
 
244
241
  Cloud SQL for PostgreSQL for LangChain
@@ -299,7 +296,7 @@ dependencies.
299
296
  Supported Python Versions
300
297
  ^^^^^^^^^^^^^^^^^^^^^^^^^
301
298
 
302
- Python >= 3.9
299
+ Python >= 3.10
303
300
 
304
301
  Mac/Linux
305
302
  ^^^^^^^^^
@@ -354,6 +351,26 @@ Use a Vector Store to store embedded data and perform vector search.
354
351
  embeddings=embedding_service
355
352
  )
356
353
 
354
+ Hybrid search
355
+ ~~~~~~~~~~~~~
356
+
357
+ The `PostgresVectorStore` supports hybrid search (dense vectors + full text) for more comprehensive and relevant search results.
358
+
359
+ .. code-block:: python
360
+
361
+ from langchain_google_cloud_sql_pg import HybridSearchConfig, reciprocal_rank_fusion
362
+
363
+ vs = PostgresVectorStore.create_sync(
364
+ engine=engine,
365
+ table_name=TABLE_NAME,
366
+ embedding_service=embedding,
367
+ hybrid_search_config=HybridSearchConfig(
368
+ fusion_function=reciprocal_rank_fusion
369
+ ),
370
+ )
371
+ hybrid_docs = vector_store.similarity_search("products", k=5)
372
+
373
+
357
374
  See the full `Vector Store`_ tutorial.
358
375
 
359
376
  .. _`Vector Store`: https://github.com/googleapis/langchain-google-cloud-sql-pg-python/tree/main/docs/vector_store.ipynb
@@ -56,7 +56,7 @@ dependencies.
56
56
  Supported Python Versions
57
57
  ^^^^^^^^^^^^^^^^^^^^^^^^^
58
58
 
59
- Python >= 3.9
59
+ Python >= 3.10
60
60
 
61
61
  Mac/Linux
62
62
  ^^^^^^^^^
@@ -111,6 +111,26 @@ Use a Vector Store to store embedded data and perform vector search.
111
111
  embeddings=embedding_service
112
112
  )
113
113
 
114
+ Hybrid search
115
+ ~~~~~~~~~~~~~
116
+
117
+ The `PostgresVectorStore` supports hybrid search (dense vectors + full text) for more comprehensive and relevant search results.
118
+
119
+ .. code-block:: python
120
+
121
+ from langchain_google_cloud_sql_pg import HybridSearchConfig, reciprocal_rank_fusion
122
+
123
+ vs = PostgresVectorStore.create_sync(
124
+ engine=engine,
125
+ table_name=TABLE_NAME,
126
+ embedding_service=embedding,
127
+ hybrid_search_config=HybridSearchConfig(
128
+ fusion_function=reciprocal_rank_fusion
129
+ ),
130
+ )
131
+ hybrid_docs = vector_store.similarity_search("products", k=5)
132
+
133
+
114
134
  See the full `Vector Store`_ tutorial.
115
135
 
116
136
  .. _`Vector Store`: https://github.com/googleapis/langchain-google-cloud-sql-pg-python/tree/main/docs/vector_store.ipynb
@@ -4,19 +4,16 @@ dynamic = ["version"]
4
4
  description = "LangChain integrations for Google Cloud SQL for PostgreSQL"
5
5
  readme = "README.rst"
6
6
  license = {file = "LICENSE"}
7
- requires-python = ">=3.9"
7
+ requires-python = ">=3.10"
8
8
  authors = [
9
9
  {name = "Google LLC", email = "googleapis-packages@google.com"}
10
10
  ]
11
11
 
12
12
  dependencies = [
13
13
  "cloud-sql-python-connector[asyncpg] >= 1.10.0, <2.0.0",
14
- "langchain-core>=0.2.36, <1.0.0 ",
15
14
  "numpy>=1.24.4, <3.0.0; python_version >= '3.11'",
16
15
  "numpy>=1.24.4, <=2.2.6; python_version == '3.10'",
17
- "numpy>=1.24.4, <=2.0.2; python_version <= '3.9'",
18
- "pgvector>=0.2.5, <1.0.0",
19
- "SQLAlchemy[asyncio]>=2.0.25, <3.0.0"
16
+ "langchain-postgres>=0.0.16",
20
17
  ]
21
18
 
22
19
  classifiers = [
@@ -24,10 +21,10 @@ classifiers = [
24
21
  "License :: OSI Approved :: Apache Software License",
25
22
  "Programming Language :: Python",
26
23
  "Programming Language :: Python :: 3",
27
- "Programming Language :: Python :: 3.9",
28
24
  "Programming Language :: Python :: 3.10",
29
25
  "Programming Language :: Python :: 3.11",
30
26
  "Programming Language :: Python :: 3.12",
27
+ "Programming Language :: Python :: 3.13",
31
28
  ]
32
29
 
33
30
  [tool.setuptools.dynamic]
@@ -41,17 +38,17 @@ Changelog = "https://github.com/googleapis/langchain-google-cloud-sql-pg-python/
41
38
 
42
39
  [project.optional-dependencies]
43
40
  langgraph = [
44
- "langgraph-checkpoint>=2.0.9, <3.0.0"
41
+ "langgraph-checkpoint>=4.0.0, <5.0.0"
45
42
  ]
46
43
  test = [
47
- "black[jupyter]==25.1.0",
48
- "isort==6.0.1",
49
- "mypy==1.15.0",
44
+ "black[jupyter]==26.3.1",
45
+ "isort==9.0.2",
46
+ "mypy==1.19.1",
50
47
  "pytest-asyncio==0.26.0",
51
- "pytest==8.4.1",
52
- "pytest-cov==6.2.1",
53
- "langchain-tests==0.3.20",
54
- "langgraph==0.5.2"
48
+ "pytest==8.4.2",
49
+ "pytest-cov==7.0.0",
50
+ "langchain-tests==1.1.2",
51
+ "langgraph>=1.2.2"
55
52
  ]
56
53
 
57
54
  [build-system]
@@ -65,7 +62,7 @@ target-version = ['py39']
65
62
  profile = "black"
66
63
 
67
64
  [tool.mypy]
68
- python_version = 3.9
65
+ python_version = "3.10"
69
66
  warn_unused_configs = true
70
67
  disallow_incomplete_defs = true
71
68
 
@@ -12,10 +12,17 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from langchain_postgres import Column
16
+ from langchain_postgres.v2.hybrid_search_config import (
17
+ HybridSearchConfig,
18
+ reciprocal_rank_fusion,
19
+ weighted_sum_ranking,
20
+ )
21
+
15
22
  from . import indexes
16
23
  from .chat_message_history import PostgresChatMessageHistory
17
24
  from .checkpoint import PostgresSaver
18
- from .engine import Column, PostgresEngine
25
+ from .engine import PostgresEngine
19
26
  from .loader import PostgresDocumentSaver, PostgresLoader
20
27
  from .vectorstore import PostgresVectorStore
21
28
  from .version import __version__
@@ -29,5 +36,8 @@ __all__ = [
29
36
  "PostgresLoader",
30
37
  "PostgresDocumentSaver",
31
38
  "PostgresSaver",
39
+ "HybridSearchConfig",
40
+ "reciprocal_rank_fusion",
41
+ "weighted_sum_ranking",
32
42
  "__version__",
33
43
  ]
@@ -98,7 +98,7 @@ class AsyncPostgresChatMessageHistory(BaseChatMessageHistory):
98
98
  "\n type TEXT NOT NULL"
99
99
  "\n);"
100
100
  )
101
- return cls(cls.__create_key, engine._pool, session_id, table_name)
101
+ return cls(cls.__create_key, engine._pool, session_id, table_name, schema_name)
102
102
 
103
103
  async def aadd_message(self, message: BaseMessage) -> None:
104
104
  """Append the message to the record in PostgreSQL"""
@@ -276,7 +276,9 @@ class AsyncPostgresSaver(BaseCheckpointSaver[str]):
276
276
 
277
277
  async with self.pool.connect() as conn:
278
278
  type_, serialized_checkpoint = self.serde.dumps_typed(checkpoint)
279
- serialized_metadata = self.jsonplus_serde.dumps(metadata)
279
+ serialized_metadata = json.dumps(metadata, ensure_ascii=False).encode(
280
+ "utf-8", "ignore"
281
+ )
280
282
  await conn.execute(
281
283
  text(query),
282
284
  {
@@ -409,7 +411,7 @@ class AsyncPostgresSaver(BaseCheckpointSaver[str]):
409
411
  (value["type"], value["checkpoint"])
410
412
  ),
411
413
  metadata=(
412
- self.jsonplus_serde.loads(value["metadata"]) # type: ignore
414
+ json.loads(value["metadata"]) # type: ignore
413
415
  if value["metadata"] is not None
414
416
  else {}
415
417
  ),
@@ -494,7 +496,7 @@ class AsyncPostgresSaver(BaseCheckpointSaver[str]):
494
496
  },
495
497
  checkpoint=self.serde.loads_typed((value["type"], value["checkpoint"])),
496
498
  metadata=(
497
- self.jsonplus_serde.loads(value["metadata"]) # type: ignore
499
+ json.loads(value["metadata"]) # type: ignore
498
500
  if value["metadata"] is not None
499
501
  else {}
500
502
  ),
@@ -0,0 +1,25 @@
1
+ # Copyright 2024 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ # TODO: Remove below import when minimum supported Python version is 3.10
16
+ from __future__ import annotations
17
+
18
+ from langchain_postgres.v2.async_vectorstore import AsyncPGVectorStore
19
+
20
+
21
+ class AsyncPostgresVectorStore(AsyncPGVectorStore):
22
+ """Google Cloud SQL for PostgreSQL Vector Store class"""
23
+
24
+ def __init__(self, *args, **kwargs):
25
+ super().__init__(*args, **kwargs)
@@ -24,6 +24,7 @@ import aiohttp
24
24
  import google.auth # type: ignore
25
25
  import google.auth.transport.requests # type: ignore
26
26
  from google.cloud.sql.connector import Connector, IPTypes, RefreshStrategy
27
+ from langchain_postgres import Column, PGEngine
27
28
  from sqlalchemy import MetaData, Table, text
28
29
  from sqlalchemy.engine import URL
29
30
  from sqlalchemy.exc import InvalidRequestError
@@ -78,58 +79,10 @@ async def _get_iam_principal_email(
78
79
  return email.replace(".gserviceaccount.com", "")
79
80
 
80
81
 
81
- @dataclass
82
- class Column:
83
- name: str
84
- data_type: str
85
- nullable: bool = True
86
-
87
- def __post_init__(self):
88
- """Check if initialization parameters are valid.
89
-
90
- Raises:
91
- ValueError: Raises error if Column name is not string.
92
- ValueError: Raises error if data_type is not type string.
93
- """
94
- if not isinstance(self.name, str):
95
- raise ValueError("Column name must be type string")
96
- if not isinstance(self.data_type, str):
97
- raise ValueError("Column data_type must be type string")
98
-
99
-
100
- class PostgresEngine:
82
+ class PostgresEngine(PGEngine):
101
83
  """A class for managing connections to a Cloud SQL for Postgres database."""
102
84
 
103
85
  _connector: Optional[Connector] = None
104
- _default_loop: Optional[asyncio.AbstractEventLoop] = None
105
- _default_thread: Optional[Thread] = None
106
- __create_key = object()
107
-
108
- def __init__(
109
- self,
110
- key: object,
111
- pool: AsyncEngine,
112
- loop: Optional[asyncio.AbstractEventLoop],
113
- thread: Optional[Thread],
114
- ):
115
- """PostgresEngine constructor.
116
-
117
- Args:
118
- key (object): Prevent direct constructor usage.
119
- pool (AsyncEngine): Async engine connection pool.
120
- loop (Optional[asyncio.AbstractEventLoop]): Async event loop used to create the engine.
121
- thread (Optional[Thread]): Thread used to create the engine async.
122
-
123
- Raises:
124
- Exception: If the constructor is called directly by the user.
125
- """
126
- if key != PostgresEngine.__create_key:
127
- raise Exception(
128
- "Only create class through 'create' or 'create_sync' methods!"
129
- )
130
- self._pool = pool
131
- self._loop = loop
132
- self._thread = thread
133
86
 
134
87
  @classmethod
135
88
  async def _create(
@@ -219,7 +172,7 @@ class PostgresEngine:
219
172
  async_creator=getconn,
220
173
  **engine_args,
221
174
  )
222
- return cls(cls.__create_key, engine, loop, thread)
175
+ return cls(PGEngine._PGEngine__create_key, engine, loop, thread) # type: ignore
223
176
 
224
177
  @classmethod
225
178
  def __start_background_loop(
@@ -354,13 +307,22 @@ class PostgresEngine:
354
307
  return await asyncio.wrap_future(future)
355
308
 
356
309
  @classmethod
357
- def from_engine(
310
+ def from_connection_string(
358
311
  cls,
359
- engine: AsyncEngine,
360
- loop: Optional[asyncio.AbstractEventLoop] = None,
312
+ url: str | URL,
313
+ **kwargs: Any,
361
314
  ) -> PostgresEngine:
362
- """Create an PostgresEngine instance from an AsyncEngine."""
363
- return cls(cls.__create_key, engine, loop, None)
315
+ """Create an PostgresEngine instance from arguments. These parameters are pass directly into sqlalchemy's create_async_engine function.
316
+ Args:
317
+ url (Union[str | URL]): the URL used to connect to a database
318
+ **kwargs (Any, optional): sqlalchemy `create_async_engine` arguments
319
+ Raises:
320
+ ValueError: If `postgresql+asyncpg` is not specified as the PG driver
321
+ Returns:
322
+ PostgresEngine
323
+ """
324
+
325
+ return PostgresEngine.from_engine_args(url=url, **kwargs)
364
326
 
365
327
  @classmethod
366
328
  def from_engine_args(
@@ -396,198 +358,7 @@ class PostgresEngine:
396
358
  raise ValueError("Driver must be type 'postgresql+asyncpg'")
397
359
 
398
360
  engine = create_async_engine(url, **kwargs)
399
- return cls(cls.__create_key, engine, cls._default_loop, cls._default_thread)
400
-
401
- async def _run_as_async(self, coro: Awaitable[T]) -> T:
402
- """Run an async coroutine asynchronously"""
403
- # If a loop has not been provided, attempt to run in current thread
404
- if not self._loop:
405
- return await coro
406
- # Otherwise, run in the background thread
407
- return await asyncio.wrap_future(
408
- asyncio.run_coroutine_threadsafe(coro, self._loop)
409
- )
410
-
411
- def _run_as_sync(self, coro: Awaitable[T]) -> T:
412
- """Run an async coroutine synchronously"""
413
- if not self._loop:
414
- raise Exception(
415
- "Engine was initialized without a background loop and cannot call sync methods."
416
- )
417
- return asyncio.run_coroutine_threadsafe(coro, self._loop).result()
418
-
419
- async def close(self) -> None:
420
- """Dispose of connection pool"""
421
- await self._run_as_async(self._pool.dispose())
422
-
423
- async def _ainit_vectorstore_table(
424
- self,
425
- table_name: str,
426
- vector_size: int,
427
- schema_name: str = "public",
428
- content_column: str = "content",
429
- embedding_column: str = "embedding",
430
- metadata_columns: list[Column] = [],
431
- metadata_json_column: str = "langchain_metadata",
432
- id_column: Union[str, Column] = "langchain_id",
433
- overwrite_existing: bool = False,
434
- store_metadata: bool = True,
435
- ) -> None:
436
- """
437
- Create a table for saving of vectors to be used with PostgresVectorStore.
438
-
439
- Args:
440
- table_name (str): The Postgres database table name.
441
- vector_size (int): Vector size for the embedding model to be used.
442
- schema_name (str): The schema name to store Postgres database table.
443
- Default: "public".
444
- content_column (str): Name of the column to store document content.
445
- Default: "page_content".
446
- embedding_column (str) : Name of the column to store vector embeddings.
447
- Default: "embedding".
448
- metadata_columns (list[Column]): A list of Columns to create for custom
449
- metadata. Default: []. Optional.
450
- metadata_json_column (str): The column to store extra metadata in JSON format.
451
- Default: "langchain_metadata". Optional.
452
- id_column (Union[str, Column]) : Column to store ids.
453
- Default: "langchain_id" column name with data type UUID. Optional.
454
- overwrite_existing (bool): Whether to drop existing table. Default: False.
455
- store_metadata (bool): Whether to store metadata in the table.
456
- Default: True.
457
- Raises:
458
- :class:`DuplicateTableError <asyncpg.exceptions.DuplicateTableError>`: if table already exists and overwrite flag is not set.
459
- :class:`UndefinedObjectError <asyncpg.exceptions.UndefinedObjectError>`: if the data type of the id column is not a postgreSQL data type.
460
- """
461
- async with self._pool.connect() as conn:
462
- await conn.execute(text("CREATE EXTENSION IF NOT EXISTS vector"))
463
- await conn.commit()
464
-
465
- if overwrite_existing:
466
- async with self._pool.connect() as conn:
467
- await conn.execute(
468
- text(f'DROP TABLE IF EXISTS "{schema_name}"."{table_name}"')
469
- )
470
- await conn.commit()
471
-
472
- id_data_type = "UUID" if isinstance(id_column, str) else id_column.data_type
473
- id_column_name = id_column if isinstance(id_column, str) else id_column.name
474
-
475
- query = f"""CREATE TABLE "{schema_name}"."{table_name}"(
476
- "{id_column_name}" {id_data_type} PRIMARY KEY,
477
- "{content_column}" TEXT NOT NULL,
478
- "{embedding_column}" vector({vector_size}) NOT NULL"""
479
- for column in metadata_columns:
480
- nullable = "NOT NULL" if not column.nullable else ""
481
- query += f',\n"{column.name}" {column.data_type} {nullable}'
482
- if store_metadata:
483
- query += f""",\n"{metadata_json_column}" JSON"""
484
- query += "\n);"
485
-
486
- async with self._pool.connect() as conn:
487
- await conn.execute(text(query))
488
- await conn.commit()
489
-
490
- async def ainit_vectorstore_table(
491
- self,
492
- table_name: str,
493
- vector_size: int,
494
- schema_name: str = "public",
495
- content_column: str = "content",
496
- embedding_column: str = "embedding",
497
- metadata_columns: list[Column] = [],
498
- metadata_json_column: str = "langchain_metadata",
499
- id_column: Union[str, Column] = "langchain_id",
500
- overwrite_existing: bool = False,
501
- store_metadata: bool = True,
502
- ) -> None:
503
- """
504
- Create a table for saving of vectors to be used with PostgresVectorStore.
505
-
506
- Args:
507
- table_name (str): The Postgres database table name.
508
- vector_size (int): Vector size for the embedding model to be used.
509
- schema_name (str): The schema name to store Postgres database table.
510
- Default: "public".
511
- content_column (str): Name of the column to store document content.
512
- Default: "page_content".
513
- embedding_column (str) : Name of the column to store vector embeddings.
514
- Default: "embedding".
515
- metadata_columns (list[Column]): A list of Columns to create for custom
516
- metadata. Default: []. Optional.
517
- metadata_json_column (str): The column to store extra metadata in JSON format.
518
- Default: "langchain_metadata". Optional.
519
- id_column (Union[str, Column]) : Column to store ids.
520
- Default: "langchain_id" column name with data type UUID. Optional.
521
- overwrite_existing (bool): Whether to drop existing table. Default: False.
522
- store_metadata (bool): Whether to store metadata in the table.
523
- Default: True.
524
- """
525
- await self._run_as_async(
526
- self._ainit_vectorstore_table(
527
- table_name,
528
- vector_size,
529
- schema_name,
530
- content_column,
531
- embedding_column,
532
- metadata_columns,
533
- metadata_json_column,
534
- id_column,
535
- overwrite_existing,
536
- store_metadata,
537
- )
538
- )
539
-
540
- def init_vectorstore_table(
541
- self,
542
- table_name: str,
543
- vector_size: int,
544
- schema_name: str = "public",
545
- content_column: str = "content",
546
- embedding_column: str = "embedding",
547
- metadata_columns: list[Column] = [],
548
- metadata_json_column: str = "langchain_metadata",
549
- id_column: Union[str, Column] = "langchain_id",
550
- overwrite_existing: bool = False,
551
- store_metadata: bool = True,
552
- ) -> None:
553
- """
554
- Create a table for saving of vectors to be used with PostgresVectorStore.
555
-
556
- Args:
557
- table_name (str): The Postgres database table name.
558
- vector_size (int): Vector size for the embedding model to be used.
559
- schema_name (str): The schema name to store Postgres database table.
560
- Default: "public".
561
- content_column (str): Name of the column to store document content.
562
- Default: "page_content".
563
- embedding_column (str) : Name of the column to store vector embeddings.
564
- Default: "embedding".
565
- metadata_columns (list[Column]): A list of Columns to create for custom
566
- metadata. Default: []. Optional.
567
- metadata_json_column (str): The column to store extra metadata in JSON format.
568
- Default: "langchain_metadata". Optional.
569
- id_column (Union[str, Column]) : Column to store ids.
570
- Default: "langchain_id" column name with data type UUID. Optional.
571
- overwrite_existing (bool): Whether to drop existing table. Default: False.
572
- store_metadata (bool): Whether to store metadata in the table.
573
- Default: True.
574
- Raises:
575
- :class:`UndefinedObjectError <asyncpg.exceptions.UndefinedObjectError>`: if the `ids` data type does not match that of the `id_column`.
576
- """
577
- self._run_as_sync(
578
- self._ainit_vectorstore_table(
579
- table_name,
580
- vector_size,
581
- schema_name,
582
- content_column,
583
- embedding_column,
584
- metadata_columns,
585
- metadata_json_column,
586
- id_column,
587
- overwrite_existing,
588
- store_metadata,
589
- )
590
- )
361
+ return cls(PGEngine._PGEngine__create_key, engine, cls._default_loop, cls._default_thread) # type: ignore
591
362
 
592
363
  async def _ainit_chat_history_table(
593
364
  self, table_name: str, schema_name: str = "public"
@@ -0,0 +1,27 @@
1
+ # Copyright 2024 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from langchain_postgres.v2.indexes import (
16
+ DEFAULT_DISTANCE_STRATEGY,
17
+ DEFAULT_INDEX_NAME_SUFFIX,
18
+ BaseIndex,
19
+ DistanceStrategy,
20
+ ExactNearestNeighbor,
21
+ HNSWIndex,
22
+ HNSWQueryOptions,
23
+ IVFFlatIndex,
24
+ IVFFlatQueryOptions,
25
+ QueryOptions,
26
+ StrategyMixin,
27
+ )