diff --git a/env.example b/env.example index 5eef3913..f59c2969 100644 --- a/env.example +++ b/env.example @@ -310,6 +310,14 @@ POSTGRES_IVFFLAT_LISTS=100 # POSTGRES_SSL_ROOT_CERT=/path/to/ca-cert.pem # POSTGRES_SSL_CRL=/path/to/crl.pem +### 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_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 NEO4J_USERNAME=neo4j diff --git a/lightrag/kg/postgres_impl.py b/lightrag/kg/postgres_impl.py index f22674c0..50c2108f 100644 --- a/lightrag/kg/postgres_impl.py +++ b/lightrag/kg/postgres_impl.py @@ -74,6 +74,12 @@ 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") + + # 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") @@ -160,6 +166,15 @@ class PostgreSQLDB: "max_size": self.max, } + # 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() if ssl_context is not None: @@ -173,6 +188,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 +861,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 +1401,15 @@ class ClientManager: config.get("postgres", "ivfflat_lists", fallback="100"), ) ), + # Server settings for Supabase + "server_settings": os.environ.get( + "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