52 Kilometers, Two Races, One Cloud Migration — Stockholm Marathon Meets MySQL HeatWave and Oracle DB 23ai

At Oracle Sweden, we take health and wellbeing seriously — so seriously, in fact, that many of us participated in both the Stockholm Marathon and Blodomloppet in 2025 as part of our internal Oracle Run Club. These events not only reflect our commitment to wellness but also serve as a perfect opportunity to demonstrate how Oracle’s modern cloud technologies can support real-world, diverse data use cases. Oracle is no longer just a relational database company — it now delivers powerful cloud-native services, including MySQL HeatWave and Oracle Database 23ai, both recognized in the Gartner Magic Quadrant for their innovation, performance, and support for all modern data types.

In this guide, I will walk you through how to manage and migrate image data from two major 2025 running events — the Stockholm Marathon and Blodomloppet. I will begin by storing event images in MongoDB, then retrieving and transferring them into one of two powerful cloud databases: MySQL HeatWave, which excels at high-speed queries and real-time analytics, or Oracle DB 23ai on Cloud, designed for AI-driven workloads, JSON handling, and advanced vector search. The entire process is implemented using Python, ensuring a streamlined and developer-friendly workflow. Choosing the right target database depends on your goals: if you are focused on building dashboards, generating reports, or executing fast queries across large datasets, MySQL HeatWave offers excellent performance and cost-efficiency. However, if your needs include AI/ML tasks — such as image tagging, facial recognition, or semantic similarity — Oracle DB 23ai provides enterprise-grade features with integrated GenAI and a powerful hybrid relational/JSON architecture.

1- Install MongoDB (Local Development) for macOS (Homebrew) in your terminal bash:

-mac ~ % brew tap mongodb/brew
 
==> Auto-updating Homebrew...
Adjust how often this is run with HOMEBREW_AUTO_UPDATE_SECS or disable with
HOMEBREW_NO_AUTO_UPDATE. Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
==> Auto-updated Homebrew!
Updated 2 taps (homebrew/core and homebrew/cask).
==> New Formulae
 
....
 
Receiving objects: 100% (1603/1603), 350.92 KiB | 2.58 MiB/s, done.
Resolving deltas: 100% (972/972), done.
Tapped 20 formulae (38 files, 448.8KB).
 
-mac ~ % brew install mongodb-community@6.0
 
 
==> Fetching dependencies for mongodb/brew/mongodb-community@6.0: mongodb/brew/mongodb-database-tools, brotli, c-ares, libnghttp2, libuv, openssl@3, node and mongosh
==> Fetching mongodb/brew/mongodb-database-tools
==> Downloading https://fastdl.mongodb.org/tools/db/mongodb-database-tools-macos
######################################################################### 100.0%
==> Fetching brotli
==> Downloading https://ghcr.io/v2/homebrew/core/brotli/manifests/1.1.0-2
###############################
 
....
 
######################################################################### 100.0%
==> Fetching mongodb/brew/mongodb-community@6.0
==> Downloading https://fastdl.mongodb.org/osx/mongodb-macos-arm64-6.0.24.tgz
######################################################################### 100.0%
==> Installing mongodb-community@6.0 from mongodb/brew
 
...
######################################################################### 100.0%
==> Fetching mongodb/brew/mongodb-community@6.0
==> Downloading https://fastdl.mongodb.org/osx/mongodb-macos-arm64-6.0.24.tgz
######################################################################### 100.0%
==> Installing mongodb-community@6.0 from mongodb/brew
 
 
# Start MongoDB service
~ % brew services start mongodb/brew/mongodb-community@6.0
 
==> Successfully started `mongodb-community@6.0` (label: homebrew.mxcl.mongodb-c
 
 
# Test connection
~ % mongosh
 
...
 
 
 
To help improve our products, anonymous usage data is collected and sent to MongoDB periodically (https://www.mongodb.com/legal/privacy-policy).
You can opt-out by running the disableTelemetry() command.
 
------
   The server generated these startup warnings when booting
   2025-07-06T10:59:05.451+02:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
------
 
test> 


2- Set Up MySQL HeatWave on Oracle Cloud since MySQL HeatWave is cloud-only, part of Oracle Cloud Infrastructure (OCI) and it has a prerequiste the need of create an Oracle Cloud account (https://cloud.oracle.com/) and create a MySQL DB System with HeatWave enabled

To set up MySQL HeatWave on Oracle Cloud, start by navigating to the OCI Console. From the main menu, go to DB systems (HeatWave) , then click on “Create MySQL DB System.” On the configuration page, provide a name for your system—for example, “heatwave-demo”. Choose a shape like MySQL.HeatWave.VM.Standard.E3, and make sure to enable the HeatWave Cluster by checking the appropriate box. Set a secure password for the initial admin user, then proceed to create the system. Provisioning may take a few minutes. Once your MySQL DB system is up and running, visit the instance details and locate the Public IP or DNS under the “Endpoints” section. From there, you can either create a new MySQL user or use the default root user to begin working with your database.

It takes some minutes to create it….

After 19 minutes the MySQL HeatWave was created:

Before we dive into storing race images, let us briefly review the technologies used in this project. The implementation is written in Python 3.10 or later, utilizing a combination of specialized libraries to interact with various databases. For MongoDB operations, we use PyMongo, while MySQL Connector/Python handles communication with MySQL HeatWave. To interact with Oracle DB 23ai on Cloud, the cx_Oracle library is used. The sample images used in this workflow are named stockholm2025.jpg and blodomloppet2025.jpg, representing two major running events in Sweden. This guide will provide complete code for all operations, including the Oracle DB 23ai integration. However, I will not cover the installation or configuration steps for Oracle Cloud services; only the relevant Python code for uploading images to the database will be included.

3- Store Race Images into MongoDB using Jupyter Notebook:

#pip install pymongo 
#storing images into MongoDB, the images were stored as binary data directly in the document #using the Binary type from the bson module
 
from pymongo import MongoClient
from bson.binary import Binary
 
# Connect to MongoDB
client = MongoClient("mongodb://localhost:27017")
db = client['race_photos']
collection = db['event_images']
 
def store_image(filename):
    with open(filename, 'rb') as f:
        collection.insert_one({
            'filename': filename,
            'image': Binary(f.read())
        })
 
store_image("stockholm2025.jpg")
store_image("preblodomloppet2025.jpg")
store_image("blodomloppet2025.jpg")



4- Download Images from MongoDB using Jupyter Notebook:


def download_images():
    for img in collection.find():
        with open(f"{img['filename']}", "wb") as f:
            f.write(img['image'])
 
download_images()


5- Upload to MySQL HeatWave using Jupyter Notebook:

#images were stored in MySQL HeatWave using a LONGBLOB column 
import mysql.connector
 
def upload_to_mysql():
    conn = mysql.connector.connect(
        host="your-heatwave-endpoint", ##add your credentials here
        user="your-username",
        password="your-password",
        database="race_images"
    )
    cursor = conn.cursor()
    cursor.execute("""
        CREATE TABLE IF NOT EXISTS event_photos (
            id INT AUTO_INCREMENT PRIMARY KEY,
            filename VARCHAR(255),
            image LONGBLOB
        )
    """)
 
    for fname in ["stockholm2025.jpg", "blodomloppet2025.jpg"]:
        with open(fname, "rb") as f:
            cursor.execute("INSERT INTO event_photos (filename, image) VALUES (%s, %s)", (fname, f.read()))
 
    conn.commit()
    conn.close()

5- Upload to Oracle DB 23ai (Cloud) using Jupyter Notebook (If this is your choice):

import cx_Oracle
 
def upload_to_oracle():
    conn = cx_Oracle.connect(
        user="your_user", #add your user here
        password="your_password", #add your password here
        dsn="your_oracle_cloud_dsn", #add your dsn here
        encoding="UTF-8"
    )
    cursor = conn.cursor()
    cursor.execute("""
        BEGIN
            EXECUTE IMMEDIATE 'CREATE TABLE event_photos (filename VARCHAR2(255), image BLOB)';
        EXCEPTION
            WHEN OTHERS THEN
                IF SQLCODE != -955 THEN RAISE; END IF;
        END;
    """)
 
    for fname in ["downloaded_stockholm2025.jpg", "downloaded_blodomloppet2025.jpg"]:
        with open(fname, "rb") as f:
            cursor.execute("INSERT INTO event_photos (filename, image) VALUES (:1, :2)", (fname, f.read()))
 
    conn.commit()
    conn.close()

To wrap up, this is a simple example but it is helpful to compare the broader return on investment (ROI) when choosing between Oracle DB 23ai, MySQL HeatWave, and MongoDB Atlas. Oracle DB 23ai performs excellently in AI/ML workloads and offers advanced features like GenAI integration, vector search, and hybrid JSON-relational support. While its infrastructure costs are higher, it delivers a strong ROI for enterprise and AI-driven applications. MySQL HeatWave stands out for analytics-heavy scenarios, with extremely high performance per dollar and lower infrastructure costs, making it ideal for real-time reporting and dashboard use cases. MongoDB Atlas, on the other hand, remains an excellent option for rapid prototyping and developer productivity. The reason behind it is its flexible schema and ease of use. However, it may require the use of third-party tools for advanced AI functionality, which can be seen as a drawback depending on the context. Each platform has strengths, and while MongoDB remains a strong choice for agile development, both Oracle DB 23ai and MySQL HeatWave can also be excellent options for developers who need scalable, intelligent, and cloud-optimized database solutions.

Related posts