2929 RequestExtractor ,
3030)
3131
32- # Global cache for database configurations to avoid connection pool interference
3332_cached_db_configs = {} # type: Dict[str, Dict[str, Any]]
3433
3534try :
@@ -157,12 +156,9 @@ def __init__(
157156 def setup_once ():
158157 # type: () -> None
159158 _check_minimum_version (DjangoIntegration , DJANGO_VERSION )
160-
161- # Cache database configurations to avoid connection pool interference
162159 _cache_database_configurations ()
163160
164161 install_sql_hook ()
165- # Patch in our custom middleware.
166162
167163 # logs an error for every 500
168164 ignore_logger ("django.server" )
@@ -621,7 +617,9 @@ def _set_user_info(request, event):
621617
622618def _cache_database_configurations ():
623619 # type: () -> None
624- """Cache database configurations from Django settings to avoid connection pool interference."""
620+ """
621+ Cache database configurations from Django settings to avoid connection pool interference.
622+ """
625623 global _cached_db_configs
626624
627625 try :
@@ -632,39 +630,24 @@ def _cache_database_configurations():
632630 if not db_config : # Skip empty default configs
633631 continue
634632
635- try :
636- # Get database wrapper to access vendor info
637- db_wrapper = connections [alias ]
638-
633+ with capture_internal_exceptions ():
639634 _cached_db_configs [alias ] = {
640635 "db_name" : db_config .get ("NAME" ),
641636 "host" : db_config .get ("HOST" , "localhost" ),
642637 "port" : db_config .get ("PORT" ),
643- "vendor" : (
644- db_wrapper .vendor if hasattr (db_wrapper , "vendor" ) else None
645- ),
646638 "unix_socket" : db_config .get ("OPTIONS" , {}).get ("unix_socket" ),
647639 "engine" : db_config .get ("ENGINE" ),
648640 }
649641
650- logger .debug (
651- "Cached database configuration for %s: %s" ,
652- alias ,
653- {
654- k : v
655- for k , v in _cached_db_configs [alias ].items ()
656- if k != "vendor"
657- },
658- )
642+ db_wrapper = connections .get (alias )
643+ if db_wrapper is None :
644+ continue
659645
660- except Exception as e :
661- logger .debug (
662- "Failed to cache database configuration for %s: %s" , alias , e
663- )
646+ if hasattr (db_wrapper , "vendor" ):
647+ _cached_db_configs [alias ]["vendor" ] = db_wrapper .vendor
664648
665649 except Exception as e :
666650 logger .debug ("Failed to cache database configurations: %s" , e )
667- # Graceful fallback - cache remains empty
668651 _cached_db_configs = {}
669652
670653
@@ -722,7 +705,6 @@ def executemany(self, sql, param_list):
722705 span_origin = DjangoIntegration .origin_db ,
723706 ) as span :
724707 _set_db_data (span , self )
725-
726708 result = real_executemany (self , sql , param_list )
727709
728710 with capture_internal_exceptions ():
@@ -754,22 +736,22 @@ def connect(self):
754736def _set_db_data (span , cursor_or_db ):
755737 # type: (Span, Any) -> None
756738 """
757- Improved version that avoids connection pool interference by using cached
758- database configurations and specific exception handling.
739+ Set database connection data to the span.
740+
741+ Tries first to use pre-cached configuration.
742+ If that fails, it uses get_connection_params() to get the database connection
743+ parameters.
759744 """
760745 from django .core .exceptions import ImproperlyConfigured
761746
762- # Get database wrapper
763747 db = cursor_or_db .db if hasattr (cursor_or_db , "db" ) else cursor_or_db
748+ db_alias = db .alias if hasattr (db , "alias" ) else None
764749
765- # Set vendor (always safe, no connection access)
766- span .set_data (SPANDATA .DB_SYSTEM , db .vendor )
767-
768- # Get the database alias (supports .using() queries)
769- db_alias = db .alias
750+ if hasattr (db , "vendor" ):
751+ span .set_data (SPANDATA .DB_SYSTEM , db .vendor )
770752
771- # Method 1: Use pre-cached configuration (FASTEST, NO CONNECTION ACCESS)
772- cached_config = _cached_db_configs .get (db_alias )
753+ # Use pre-cached configuration
754+ cached_config = _cached_db_configs .get (db_alias ) if db_alias else None
773755 if cached_config :
774756 if cached_config ["db_name" ]:
775757 span .set_data (SPANDATA .DB_NAME , cached_config ["db_name" ])
@@ -781,38 +763,28 @@ def _set_db_data(span, cursor_or_db):
781763 span .set_data (SPANDATA .SERVER_SOCKET_ADDRESS , cached_config ["unix_socket" ])
782764 return
783765
784- # Method 2: Dynamic fallback using get_connection_params() (NO CONNECTION ACCESS )
766+ # Fallback to using get_connection_params()
785767 try :
786768 connection_params = db .get_connection_params ()
787769
788- # Extract database name
789770 db_name = connection_params .get ("dbname" ) or connection_params .get ("database" )
790771 if db_name :
791772 span .set_data (SPANDATA .DB_NAME , db_name )
792773
793- # Extract host
794774 host = connection_params .get ("host" )
795775 if host :
796776 span .set_data (SPANDATA .SERVER_ADDRESS , host )
797777
798- # Extract port
799778 port = connection_params .get ("port" )
800779 if port :
801780 span .set_data (SPANDATA .SERVER_PORT , str (port ))
802781
803- # Extract unix socket
804782 unix_socket = connection_params .get ("unix_socket" )
805783 if unix_socket :
806784 span .set_data (SPANDATA .SERVER_SOCKET_ADDRESS , unix_socket )
807785
808786 except (KeyError , ImproperlyConfigured , AttributeError ) as e :
809- # Specific exceptions that get_connection_params() can raise:
810- # - KeyError: Missing required database settings (most common)
811- # - ImproperlyConfigured: Django configuration problems
812- # - AttributeError: Missing methods on database wrapper
813787 logger .debug ("Failed to get database connection params for %s: %s" , db_alias , e )
814- # Skip database metadata rather than risk connection issues
815- pass
816788
817789
818790def add_template_context_repr_sequence ():
0 commit comments