From 3348c2698cf14057a85d2ed3f00a6271f29b789e Mon Sep 17 00:00:00 2001 From: yucheng Date: Thu, 24 Sep 2026 08:43:12 +0000 Subject: [PATCH] fix(proxy-extras): name the libpq load failure when the partition check is skipped psycopg imports fine without libpq and only raises when the pq wrapper is resolved, so the skipped-check warning now carries the ImportError text and points at the system libpq the images ship Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .../litellm_proxy_extras/utils.py | 17 ++++++++++------- .../test_litellm_proxy_extras_utils.py | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/litellm-proxy-extras/litellm_proxy_extras/utils.py b/litellm-proxy-extras/litellm_proxy_extras/utils.py index 8a83c786e02..a2a849c122f 100644 --- a/litellm-proxy-extras/litellm_proxy_extras/utils.py +++ b/litellm-proxy-extras/litellm_proxy_extras/utils.py @@ -604,13 +604,15 @@ class ProxyExtrasDBManager: try: import psycopg - except ImportError: + except ImportError as exc: logger.warning( - "psycopg is not installed; skipping the LiteLLM_SpendLogs " - "partition check. If this table is partitioned (see " + "psycopg is not installed or found no libpq (%s); skipping the " + "LiteLLM_SpendLogs partition check. If this table is partitioned (see " "db_scripts/partition_spend_logs.sql), schema reconciliation " "will try to rewrite its primary key and fail. Install the " - "litellm[extra_proxy] extra, which now includes psycopg." + "litellm[extra_proxy] extra, which includes psycopg, plus the " + "system libpq it loads (the litellm images ship it).", + exc, ) return False @@ -798,10 +800,11 @@ class ProxyExtrasDBManager: try: import psycopg from psycopg import sql - except ImportError: + except ImportError as exc: logger.warning( - "psycopg is not installed; skipping the invalid index check. " - "Install the litellm[extra_proxy] extra, which includes psycopg." + "psycopg is not installed or found no libpq (%s); skipping the invalid index check. " + "Install the litellm[extra_proxy] extra, which includes psycopg, plus the system libpq.", + exc, ) return False diff --git a/tests/litellm-proxy-extras/test_litellm_proxy_extras_utils.py b/tests/litellm-proxy-extras/test_litellm_proxy_extras_utils.py index bb329264a11..3d5590ff0ae 100644 --- a/tests/litellm-proxy-extras/test_litellm_proxy_extras_utils.py +++ b/tests/litellm-proxy-extras/test_litellm_proxy_extras_utils.py @@ -3,6 +3,7 @@ import os import re import sys from pathlib import Path +from typing import Final import pytest @@ -705,6 +706,23 @@ class TestSpendLogsPartitionDetectionMissingPsycopg: "psycopg is not installed" in record.message for record in caplog.records ) + def test_missing_libpq_warning_names_the_libpq_error(self, monkeypatch, caplog): + class NoLibpq: + @staticmethod + def find_spec(name, path=None, target=None): + if name == "psycopg": + raise ImportError("no pq wrapper available.\nAttempts made:\n- couldn't import psycopg 'python'") + + for name in [m for m in sys.modules if m == "psycopg" or m.startswith("psycopg.")]: + monkeypatch.delitem(sys.modules, name) + monkeypatch.setattr(sys, "meta_path", [NoLibpq(), *sys.meta_path]) + monkeypatch.setenv("DATABASE_URL", "postgresql://u:p@localhost:5432/db") + with caplog.at_level("WARNING", logger="litellm_proxy_extras"): + assert ProxyExtrasDBManager.spend_logs_is_partitioned() is False + warning: Final = next(r.getMessage() for r in caplog.records if "partition check" in r.getMessage()) + assert "no pq wrapper available" in warning + assert "libpq" in warning + _ATTEMPT_BUDGET = 4