Skip to content

Instantly share code, notes, and snippets.

@mzpqnxow
Last active March 21, 2021 19:05
Show Gist options
  • Save mzpqnxow/404484ff4e02a73063816cd0190e329d to your computer and use it in GitHub Desktop.
Save mzpqnxow/404484ff4e02a73063816cd0190e329d to your computer and use it in GitHub Desktop.
Do basic processing on psycopg2 exceptions to print or map the Diagnostic object
def psycopg2_diag_summarize(err: psycopg2.Error, formatted_lines: bool = False) -> Union[Dict, List[str]]:
"""Return a dict representation of a psycopg2.extensions.Diagnostics object
- Dynamically produce a dict for all public members of the object using dir() to get the
attribute names
- Filter out some undesirables (None, callables, non-localized versions of strings)
- Rename a fixed list of keys to make it more conducive to pretty-printing
Uses f-strings, so needs Python >= 3.6
psycopg2 started exposing the Diagnostic object some time >= 2.5
"""
av_map = {name: getattr(err.diag, name, None) for name in dir(err.diag) if not name.startswith('_') and not callable(getattr(err.diag, name))}
# Filter out None, callables and the "non-localized" version of strings (which are effectively duplicates for us)
f_map = {k: v for k, v in av_map.items() if v is not None and not callable(v) and not k.endswith('nonlocalized')}
source_file = f_map.pop('source_file', None)
source_function = f_map.pop('source_function', None)
source_line = f_map.pop('source_line', None)
f_map['Context'] = f_map.pop('context', None)
f_map['Source'] = f'{source_file}:{source_function}() :: {source_line}'
f_map['Error Message'] = f_map.pop('message_primary', 'N/A')
f_map['Error Message Detail'] = f_map.pop('message_detail', 'N/A')
f_map['SQL State'] = f_map.pop('sqlstate', 'N/A')
if formatted_lines is True:
# Return a bunch of lines so they can be called in context from a logger
lines = [
f'===== psycopg2.extensions.Diagnostics Report =====',
f'===== EXCEPTION: {err.__class__.__name__} =====']
for key, value in sorted(f_map.items()):
lines.append( f' diag.{key:<24} = {value}')
return lines
# Return a plain key/value mapping as a dict
return f_map
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment