Ok, here is the second and final part of this topic. So lets resume from where we left off
Now that the building blocks are clear, let’s walk
through what actually happens when you run the script
The script starts by calling setup_logging(), which
ensures the log directory exists and configures a file + console logger. The
log file name includes a timestamp, so each run has its own log.
Next, load_db_credentials() reads db_credentials.txt,
parses the key/value pairs, and constructs a DbCredentials object.
If
the file is missing or any required key is missing, the script raises an error
early, before trying to connect.
get_db_connection(credentials) then
calls
cx_Oracle.connect(credentials.username, credentials.password,
credentials.dsn) and logs that the connection is being established.
From
this point on, the script can run any SQL that your Oracle user is authorised
to run.
====
build_query_definitions() produces the ordered list of QueryDefinition objects that will represent each section in the outlok mail body. A simple loop iterates over this list, and for each definition:
- run_query(connection, query_def) executes query_def.sql using pandas.read_sql().
- The resulting DataFrame has NaN values replaced with empty strings via fillna("").
- The index is reset so that row numbering in the HTML starts from 1, which makes it easier for business users to reference specific rows in emails or follow up calls.
====
dataframe_to_pretty_html(df) is responsible for turning the DataFrame into HTML and applying some basic styling.
The script defines constants such as TABLE_FONT_SIZE, TABLE_HEADER_BG, TABLE_EVEN_ROW_BG, and TABLE_BORDER to keep the look consistent across all sections.
This gives the user a readable, Outlook friendly table without needing a full templating engine.
====
For each query, the script builds an HTML block that looks roughly like:
- Section heading (query_def.name)
- Short description (query_def.description)
- Either a styled HTML table or the empty_message
- Some spacing between sections (via a SECTION_GAP constant)
Before the sections, the script adds a standard intro paragraph stored in EMAIL_INTRO_TEXT, which explains that the email shows “the latest query extracts for review”, highlights that it is a snapshot for “yesterday”, and that the message has been created as an Outlook draft for manual review and sending.
This text is easy to adjust for different business audiences or different frequency (e.g. weekly or monthly snapshots).
All of these pieces are concatenated into a single HTML string that becomes the body of the email. Because the output is pure HTML, you can further tune it with headings, colours, or additional notes without touching the database logic.
===============
If you would like to get the full code. Please leave your email address in the comment section and I'll share it
No comments:
Post a Comment