@@ -762,25 +762,58 @@ def _set_db_data(span, cursor_or_db):
762762 span .set_data (SPANDATA .SERVER_PORT , str (cached_config ["port" ]))
763763 if cached_config ["unix_socket" ]:
764764 span .set_data (SPANDATA .SERVER_SOCKET_ADDRESS , cached_config ["unix_socket" ])
765- return
765+ return # Success - exit early
766766
767- # Fallback to using the database connection to get the data .
767+ # Fallback to dynamic database metadata collection .
768768 # This is the edge case where db configuration is not in Django's `DATABASES` setting.
769769 try :
770- # Some custom backends override `__getattr__`, making it look like `cursor_or_db`
771- # actually has a `connection` and the `connection` has a `get_dsn_parameters`
772- # attribute, only to throw an error once you actually want to call it.
773- # Hence the `inspect` check whether `get_dsn_parameters` is an actual callable
774- # function.
775- is_psycopg2 = (
776- hasattr (cursor_or_db , "connection" )
777- and hasattr (cursor_or_db .connection , "get_dsn_parameters" )
778- and inspect .isroutine (cursor_or_db .connection .get_dsn_parameters )
770+ # Method 1: Try db.get_connection_params() first (NO CONNECTION ACCESS)
771+ logger .debug (
772+ "Cached db connection config retrieval failed for %s. Trying db.get_connection_params()." ,
773+ db_alias ,
779774 )
780- if is_psycopg2 :
781- connection_params = cursor_or_db .connection .get_dsn_parameters ()
782- else :
783- try :
775+ try :
776+ connection_params = db .get_connection_params ()
777+
778+ db_name = connection_params .get ("dbname" ) or connection_params .get (
779+ "database"
780+ )
781+ if db_name is not None :
782+ span .set_data (SPANDATA .DB_NAME , db_name )
783+
784+ host = connection_params .get ("host" )
785+ if host is not None :
786+ span .set_data (SPANDATA .SERVER_ADDRESS , host )
787+
788+ port = connection_params .get ("port" )
789+ if port is not None :
790+ span .set_data (SPANDATA .SERVER_PORT , str (port ))
791+
792+ unix_socket = connection_params .get ("unix_socket" )
793+ if unix_socket is not None :
794+ span .set_data (SPANDATA .SERVER_SOCKET_ADDRESS , unix_socket )
795+ return # Success - exit early to avoid connection access
796+
797+ except (KeyError , ImproperlyConfigured , AttributeError ):
798+ # Method 2: Last resort - direct connection access (CONNECTION POOL RISK)
799+ logger .debug (
800+ "db.get_connection_params() failed for %s, trying direct connection access" ,
801+ db_alias ,
802+ )
803+
804+ # Some custom backends override `__getattr__`, making it look like `cursor_or_db`
805+ # actually has a `connection` and the `connection` has a `get_dsn_parameters`
806+ # attribute, only to throw an error once you actually want to call it.
807+ # Hence the `inspect` check whether `get_dsn_parameters` is an actual callable
808+ # function.
809+ is_psycopg2 = (
810+ hasattr (cursor_or_db , "connection" )
811+ and hasattr (cursor_or_db .connection , "get_dsn_parameters" )
812+ and inspect .isroutine (cursor_or_db .connection .get_dsn_parameters )
813+ )
814+ if is_psycopg2 :
815+ connection_params = cursor_or_db .connection .get_dsn_parameters ()
816+ else :
784817 # psycopg3, only extract needed params as get_parameters
785818 # can be slow because of the additional logic to filter out default
786819 # values
@@ -793,27 +826,28 @@ def _set_db_data(span, cursor_or_db):
793826 host = cursor_or_db .connection .info .host
794827 if host and not host .startswith ("/" ):
795828 connection_params ["host" ] = host
796- except Exception :
797- connection_params = db .get_connection_params ()
798829
799- db_name = connection_params .get ("dbname" ) or connection_params .get ("database" )
800- if db_name is not None :
801- span .set_data (SPANDATA .DB_NAME , db_name )
830+ db_name = connection_params .get ("dbname" ) or connection_params .get (
831+ "database"
832+ )
833+ if db_name is not None :
834+ span .set_data (SPANDATA .DB_NAME , db_name )
802835
803- host = connection_params .get ("host" )
804- if host is not None :
805- span .set_data (SPANDATA .SERVER_ADDRESS , host )
836+ host = connection_params .get ("host" )
837+ if host is not None :
838+ span .set_data (SPANDATA .SERVER_ADDRESS , host )
806839
807- port = connection_params .get ("port" )
808- if port is not None :
809- span .set_data (SPANDATA .SERVER_PORT , str (port ))
840+ port = connection_params .get ("port" )
841+ if port is not None :
842+ span .set_data (SPANDATA .SERVER_PORT , str (port ))
810843
811- unix_socket = connection_params .get ("unix_socket" )
812- if unix_socket is not None :
813- span .set_data (SPANDATA .SERVER_SOCKET_ADDRESS , unix_socket )
844+ unix_socket = connection_params .get ("unix_socket" )
845+ if unix_socket is not None :
846+ span .set_data (SPANDATA .SERVER_SOCKET_ADDRESS , unix_socket )
814847
815- except ( KeyError , ImproperlyConfigured , AttributeError ) as e :
848+ except Exception as e :
816849 logger .debug ("Failed to get database connection params for %s: %s" , db_alias , e )
850+ # Skip database metadata rather than risk further connection issues
817851
818852
819853def add_template_context_repr_sequence ():
0 commit comments