From 108cdbe133b2d2ac62adfbba63b5ceb4a220f5ef Mon Sep 17 00:00:00 2001 From: kevinnkansah Date: Sun, 5 Oct 2025 23:29:04 +0200 Subject: [PATCH 1/5] feat: add options for PostGres connection --- env.example | 5 +++++ lightrag/kg/postgres_impl.py | 30 ++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/env.example b/env.example index 5eef3913..b82a4cf0 100644 --- a/env.example +++ b/env.example @@ -310,6 +310,11 @@ POSTGRES_IVFFLAT_LISTS=100 # POSTGRES_SSL_ROOT_CERT=/path/to/ca-cert.pem # POSTGRES_SSL_CRL=/path/to/crl.pem +### PostgreSQL Server Options (for Supabase Supavisor) +# Use this to pass extra options to the PostgreSQL connection string. +# For Supabase, you might need to set it like this: +# POSTGRES_SERVER_OPTIONS="options=reference%3D[project-ref]" + ### Neo4j Configuration NEO4J_URI=neo4j+s://xxxxxxxx.databases.neo4j.io NEO4J_USERNAME=neo4j diff --git a/lightrag/kg/postgres_impl.py b/lightrag/kg/postgres_impl.py index f22674c0..37b39b49 100644 --- a/lightrag/kg/postgres_impl.py +++ b/lightrag/kg/postgres_impl.py @@ -74,6 +74,9 @@ class PostgreSQLDB: self.hnsw_ef = config.get("hnsw_ef") self.ivfflat_lists = config.get("ivfflat_lists") + # Server settings + self.server_settings = config.get("server_settings") + if self.user is None or self.password is None or self.database is None: raise ValueError("Missing database user, password, or database") @@ -173,6 +176,24 @@ class PostgreSQLDB: connection_params["ssl"] = False logger.info(f"PostgreSQL, SSL mode set to: {self.ssl_mode}") + # Add server settings if provided + if self.server_settings: + try: + settings = {} + # The format is expected to be a query string, e.g., "key1=value1&key2=value2" + pairs = self.server_settings.split("&") + for pair in pairs: + if "=" in pair: + key, value = pair.split("=", 1) + settings[key] = value + if settings: + connection_params["server_settings"] = settings + logger.info(f"PostgreSQL, Server settings applied: {settings}") + except Exception as e: + logger.warning( + f"PostgreSQL, Failed to parse server_settings: {self.server_settings}, error: {e}" + ) + self.pool = await asyncpg.create_pool(**connection_params) # type: ignore # Ensure VECTOR extension is available @@ -828,8 +849,8 @@ class PostgreSQLDB: # Execute the migration alter_sql = f""" - ALTER TABLE {migration['table']} - ALTER COLUMN {migration['column']} TYPE {migration['new_type']} + ALTER TABLE {migration["table"]} + ALTER COLUMN {migration["column"]} TYPE {migration["new_type"]} """ await self.execute(alter_sql) @@ -1368,6 +1389,11 @@ class ClientManager: config.get("postgres", "ivfflat_lists", fallback="100"), ) ), + # Server settings for Supabase + "server_settings": os.environ.get( + "POSTGRES_SERVER_OPTIONS", + config.get("postgres", "server_options", fallback=None), + ), } @classmethod From d8a9617c0e6fc6e6e9fa1408552e4dec57b55a5a Mon Sep 17 00:00:00 2001 From: kevinnkansah Date: Mon, 6 Oct 2025 00:36:25 +0200 Subject: [PATCH 2/5] fix: fix: asyncpg bouncer connection pool error Prepared statement caching is disabled by setting `statement_cache_size=0` in the `asyncpg` connection pool parameters. This is necessary to prevent `asyncpg.exceptions.InvalidSQLStatementNameError` when using transaction-level connection poolers like Supabase Supavisor or pgbouncer, which do not support prepared statements. --- lightrag/kg/postgres_impl.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lightrag/kg/postgres_impl.py b/lightrag/kg/postgres_impl.py index 37b39b49..8fc9d590 100644 --- a/lightrag/kg/postgres_impl.py +++ b/lightrag/kg/postgres_impl.py @@ -161,6 +161,7 @@ class PostgreSQLDB: "port": self.port, "min_size": 1, "max_size": self.max, + "statement_cache_size": 0, } # Add SSL configuration if provided From 22a7b482c5f99b4c808c9e3636a12ad73efaa153 Mon Sep 17 00:00:00 2001 From: kevinnkansah Date: Mon, 6 Oct 2025 11:56:09 +0200 Subject: [PATCH 3/5] fix: renamed PostGreSQL options env variable and allowed LRU cache to be an optional env variable --- env.example | 7 +++++-- lightrag/kg/postgres_impl.py | 13 +++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/env.example b/env.example index b82a4cf0..f59c2969 100644 --- a/env.example +++ b/env.example @@ -310,10 +310,13 @@ POSTGRES_IVFFLAT_LISTS=100 # POSTGRES_SSL_ROOT_CERT=/path/to/ca-cert.pem # POSTGRES_SSL_CRL=/path/to/crl.pem -### PostgreSQL Server Options (for Supabase Supavisor) +### PostgreSQL Server Settings (for Supabase Supavisor) # Use this to pass extra options to the PostgreSQL connection string. # For Supabase, you might need to set it like this: -# POSTGRES_SERVER_OPTIONS="options=reference%3D[project-ref]" +# POSTGRES_SERVER_SETTINGS="options=reference%3D[project-ref]" + +# Default is 100 set to 0 to disable +# POSTGRES_STATEMENT_CACHE_SIZE=100 ### Neo4j Configuration NEO4J_URI=neo4j+s://xxxxxxxx.databases.neo4j.io diff --git a/lightrag/kg/postgres_impl.py b/lightrag/kg/postgres_impl.py index 8fc9d590..99a93266 100644 --- a/lightrag/kg/postgres_impl.py +++ b/lightrag/kg/postgres_impl.py @@ -76,6 +76,7 @@ class PostgreSQLDB: # Server settings self.server_settings = config.get("server_settings") + self.statement_cache_size = int(config.get("statement_cache_size")) if self.user is None or self.password is None or self.database is None: raise ValueError("Missing database user, password, or database") @@ -161,9 +162,13 @@ class PostgreSQLDB: "port": self.port, "min_size": 1, "max_size": self.max, - "statement_cache_size": 0, + "statement_cache_size": self.statement_cache_size, } + logger.info( + f"PostgreSQL, statement LRU cache size set as: {self.statement_cache_size}" + ) + # Add SSL configuration if provided ssl_context = self._create_ssl_context() if ssl_context is not None: @@ -1392,9 +1397,13 @@ class ClientManager: ), # Server settings for Supabase "server_settings": os.environ.get( - "POSTGRES_SERVER_OPTIONS", + "POSTGRES_SERVER_SETTINGS", config.get("postgres", "server_options", fallback=None), ), + "statement_cache_size": os.environ.get( + "POSTGRES_STATEMENT_CACHE_SIZE", + config.get("postgres", "statement_cache_size", fallback=None), + ), } @classmethod From fdcb034da0378ec1dcb31b1ddec542d829d3faa2 Mon Sep 17 00:00:00 2001 From: kevinnkansah Date: Mon, 6 Oct 2025 12:01:40 +0200 Subject: [PATCH 4/5] chore: distinguish settings --- lightrag/kg/postgres_impl.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lightrag/kg/postgres_impl.py b/lightrag/kg/postgres_impl.py index 99a93266..4e6658b9 100644 --- a/lightrag/kg/postgres_impl.py +++ b/lightrag/kg/postgres_impl.py @@ -76,6 +76,8 @@ class PostgreSQLDB: # Server settings self.server_settings = config.get("server_settings") + + # Statement LRU cache size self.statement_cache_size = int(config.get("statement_cache_size")) if self.user is None or self.password is None or self.database is None: From f2c0b41e789dc42049b943d0e93b06c53072783b Mon Sep 17 00:00:00 2001 From: yangdx Date: Tue, 7 Oct 2025 22:57:21 +0800 Subject: [PATCH 5/5] Make PostgreSQL statement_cache_size configuration optional MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Remove forced int conversion • Allow None values for cache size • Add conditional parameter setting --- lightrag/kg/postgres_impl.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lightrag/kg/postgres_impl.py b/lightrag/kg/postgres_impl.py index 4e6658b9..50c2108f 100644 --- a/lightrag/kg/postgres_impl.py +++ b/lightrag/kg/postgres_impl.py @@ -77,8 +77,8 @@ class PostgreSQLDB: # Server settings self.server_settings = config.get("server_settings") - # Statement LRU cache size - self.statement_cache_size = int(config.get("statement_cache_size")) + # Statement LRU cache size (keep as-is, allow None for optional configuration) + self.statement_cache_size = config.get("statement_cache_size") if self.user is None or self.password is None or self.database is None: raise ValueError("Missing database user, password, or database") @@ -164,12 +164,16 @@ class PostgreSQLDB: "port": self.port, "min_size": 1, "max_size": self.max, - "statement_cache_size": self.statement_cache_size, } - logger.info( - f"PostgreSQL, statement LRU cache size set as: {self.statement_cache_size}" - ) + # Only add statement_cache_size if it's configured + if self.statement_cache_size is not None: + connection_params["statement_cache_size"] = int( + self.statement_cache_size + ) + logger.info( + f"PostgreSQL, statement LRU cache size set as: {self.statement_cache_size}" + ) # Add SSL configuration if provided ssl_context = self._create_ssl_context()