Data loading, with the help of AI
In today’s fast-paced development world, efficiency is paramount. AI can significantly accelerate the coding process, including the creation of scripts to interact with various data formats. This blog post will explore how to use AI assistance to generate Python code for loading a custom XML file.
This is a use case for those of us who work with data, that we can use to solve challenges which we have in development. While it’s a specific example, the approach is very re-usable and can be applied to many sources and databases.
Using AI to parse an XML file and create python code to load it to a MySQL database
For the sake of simplicity, and what’s going to be familiar to most data engineers (including open source software), I’m using an XML file I found, and coding in python loading to a MySQL database.
What is XML?
For anyone who isn’t so familiar with it (most technologies use json now) XML (Extensible Markup Language) is a simple, text-based format for representing structured data. It’s like a universal language that computers and humans can both understand.
Here’s a breakdown:
- Structure: XML uses tags (like
<name>
,<age>
) to define the structure and meaning of the data. - Data: The actual information is placed within these tags.
- Flexibility: You can create your own custom tags, making it adaptable to various data types and structures.
A simple sample example is:
<person> <name>John Doe</name> <age>30</age> <city>New York</city> </person>
My (more complicated) XML file
For this example, I’ve found an XML file which contains nested structured data. We can envisage having a collection of these files which we have to understand and load into a format which is usable for data consumption (cut down example below, full file can be seen on my github).
<?xml version="1.0" encoding="utf-8"?> <product id="Animated Canvases" name="Animated Canvases" version="1" singlecontent="true"> <volume id="Animated Canvases Collection 3" name="Animated Canvases Collection 3" number="3" sourcefiletype="mov" preview_discid="ACNV_V03D01D_R1" preview_suffix=".mov" preview_install_dir="Juicer3" preview_path_on_disc="Juicer3/" preview_thumbnail_suffix=".jpg" install_size_img="1" install_size_img_mov="10" totalPreviewSize="185" totalSourceSize="14464.62" baseJ3Version="3.03 Build 258"> <disc id="ACNV_V03D01D_R1" number="1"> <parent id="Source"> <content id="All Star_HD" type="1" name="" originalfps="30" frames="300" description="Animated Background" resolution="hd" resx="1920" resy="1080" base=""><keywords></keywords></content> <content id="Amber Rays_HD" type="1" name="" originalfps="30" frames="300" description="Animated Background" resolution="hd" resx="1920" resy="1080" base=""><keywords></keywords></content> <content id="Approaching Doom_HD" type="1" name="" originalfps="30" frames="600" description="Animated Background" resolution="hd" resx="1920" resy="1080" base=""><keywords></keywords></content> </parent> </disc> <disc id="ACNV_V03D02D_R1" number="2"> <parent id="Source"> <content id="Hiding Magic_HD" type="1" name="" originalfps="30" frames="300" description="Animated Background" resolution="hd" resx="1920" resy="1080" base=""><keywords></keywords></content> <content id="Higher Than The Sky_HD" type="1" name="" originalfps="30" frames="450" description="Animated Background" resolution="hd" resx="1920" resy="1080" base=""><keywords></keywords></content> </parent> </disc> </volume> </product>
Historically I’d use a local text editor (with syntax highlighting) to explore the file and work out what objects are in it, or an online equivalent such as: https://jsonformatter.org/xml-formatter
Using AI
In this case, I’m using ChatGPT to speed up my process. You can see the whole conversation here (the relevant parts are copied below).
Viewing the structure and content of the file
Yes, XML is very human readable, with indentation it’s even clearer what the hierarchy is. But asking AI to do some of this is even more readable.
Describe the hierarchy of data structures in the attached XML file
Click to view full response
The hierarchy of data structures in the XML file is organized as follows:
Root Element:
<product>
: Represents the top-level element of the file. It includes attributes like id
, name
, version
, and others. This serves as the main container for all subsequent elements.
Volume:
<volume>
: Nested within <product>
. Represents a collection of discs and related content. It includes attributes such as id
, name
, number
, and metadata about file types and sizes.
Disc:
<disc>
: Nested within <volume>
. Represents individual discs in the collection. Each <disc>
has attributes like id
and number
.
Parent:
<parent>
: Nested within <disc>
. Represents a grouping for source content, identified by an id
attribute, usually set to “Source”.
Content:
<content>
: Nested within <parent>
. Represents individual animated background items. Each <content>
element contains attributes like id
, type
, name
, description
, resolution
, and frame-related metadata (e.g., originalfps
, frames
).
Keywords:
<keywords>
: Nested within <content>
. A placeholder element for additional metadata about each animated background item. It is currently empty in the provided XML file.
Example Hierarchy
<product>
<volume>
<disc>
<parent>
<content>
<keywords>
This hierarchy reflects a clear structure to organize animated background content across collections, discs, and specific items within those discs.
Convert this xml into tables for product, volume, disc, and content
Click to view full response
Here’s a tabular representation of the XML data, broken down by Product, Volume, Disc, and Content.
Table: Product
ID | Name | Version | SingleContent |
---|---|---|---|
Animated Canvases | Animated Canvases | 1 | true |
Table: Volume
ID | Name | Number | SourceFileType | PreviewDiscID | PreviewSuffix | PreviewInstallDir | PreviewPathOnDisc | PreviewThumbnailSuffix | InstallSizeImg | InstallSizeImgMov | TotalPreviewSize | TotalSourceSize | BaseJ3Version |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Animated Canvases Collection 3 | Animated Canvases Collection 3 | 3 | mov | ACNV_V03D01D_R1 | .mov | Juicer3 | Juicer3/ | .jpg | 1 | 10 | 185 | 14464.62 | 3.03 Build 258 |
Table: Disc
ID | VolumeID | Number |
---|---|---|
ACNV_V03D01D_R1 | Animated Canvases Collection 3 | 1 |
ACNV_V03D02D_R1 | Animated Canvases Collection 3 | 2 |
Table: Content
ID | DiscID | Type | Name | OriginalFPS | Frames | Description | Resolution | ResX | ResY | Base | Keywords |
---|---|---|---|---|---|---|---|---|---|---|---|
All Star_HD | ACNV_V03D01D_R1 | 1 | 30 | 300 | Animated Background | hd | 1920 | 1080 | |||
Amber Rays_HD | ACNV_V03D01D_R1 | 1 | 30 | 300 | Animated Background | hd | 1920 | 1080 | |||
Approaching Doom_HD | ACNV_V03D01D_R1 | 1 | 30 | 600 | Animated Background | hd | 1920 | 1080 | |||
Balloon Rise_HD | ACNV_V03D01D_R1 | 1 | 30 | 600 | Animated Background | hd | 1920 | 1080 | |||
Blending Pipes_HD | ACNV_V03D01D_R1 | 1 | 30 | 450 | Animated Background | hd | 1920 | 1080 | |||
Bundle Of Joy_HD | ACNV_V03D01D_R1 | 1 | 30 | 600 | Animated Background | hd | 1920 | 1080 | |||
Center Of Attention_HD | ACNV_V03D01D_R1 | 1 | 30 | 300 | Animated Background | hd | 1920 | 1080 | |||
Hiding Magic_HD | ACNV_V03D02D_R1 | 1 | 30 | 300 | Animated Background | hd | 1920 | 1080 | |||
Higher Than The Sky_HD | ACNV_V03D02D_R1 | 1 | 30 | 450 | Animated Background | hd | 1920 | 1080 |
This approach captures a normalized structure suitable for a database. Each table includes key fields that uniquely identify and relate the elements. If needed, additional rows can be added for the remaining content.
It didn’t get it exactly right, an ID was missing, fortunately I can ask for it to be added
include disc id for content, volume id for disc, product id for volume
Click to view full response
Here’s the updated tabular representation with the Product ID included in the Volume table:
Table: Product
ID | Name | Version | SingleContent |
---|---|---|---|
Animated Canvases | Animated Canvases | 1 | true |
Table: Volume
ID | ProductID | Name | Number | SourceFileType | PreviewDiscID | PreviewSuffix | PreviewInstallDir | PreviewPathOnDisc | PreviewThumbnailSuffix | InstallSizeImg | InstallSizeImgMov | TotalPreviewSize | TotalSourceSize | BaseJ3Version |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Animated Canvases Collection 3 | Animated Canvases | Animated Canvases Collection 3 | 3 | mov | ACNV_V03D01D_R1 | .mov | Juicer3 | Juicer3/ | .jpg | 1 | 10 | 185 | 14464.62 | 3.03 Build 258 |
Table: Disc
ID | VolumeID | Number |
---|---|---|
ACNV_V03D01D_R1 | Animated Canvases Collection 3 | 1 |
ACNV_V03D02D_R1 | Animated Canvases Collection 3 | 2 |
Table: Content
ID | DiscID | Type | Name | OriginalFPS | Frames | Description | Resolution | ResX | ResY | Base | Keywords |
---|---|---|---|---|---|---|---|---|---|---|---|
All Star_HD | ACNV_V03D01D_R1 | 1 | 30 | 300 | Animated Background | hd | 1920 | 1080 | |||
Amber Rays_HD | ACNV_V03D01D_R1 | 1 | 30 | 300 | Animated Background | hd | 1920 | 1080 | |||
Approaching Doom_HD | ACNV_V03D01D_R1 | 1 | 30 | 600 | Animated Background | hd | 1920 | 1080 | |||
Balloon Rise_HD | ACNV_V03D01D_R1 | 1 | 30 | 600 | Animated Background | hd | 1920 | 1080 | |||
Blending Pipes_HD | ACNV_V03D01D_R1 | 1 | 30 | 450 | Animated Background | hd | 1920 | 1080 | |||
Bundle Of Joy_HD | ACNV_V03D01D_R1 | 1 | 30 | 600 | Animated Background | hd | 1920 | 1080 | |||
Center Of Attention_HD | ACNV_V03D01D_R1 | 1 | 30 | 300 | Animated Background | hd | 1920 | 1080 | |||
Hiding Magic_HD | ACNV_V03D02D_R1 | 1 | 30 | 300 | Animated Background | hd | 1920 | 1080 | |||
Higher Than The Sky_HD | ACNV_V03D02D_R1 | 1 | 30 | 450 | Animated Background | hd | 1920 | 1080 |
This updated structure ensures that Volume is directly associated with the Product, creating a complete relational model.
Creating the code to load the data
Just a question away for the part that can take more time as a developer.
generate python code to extract the data from the XML in this structure, and load it into a MySQL database
Click to view full response
Here’s the Python code to extract data from the XML file and load it into a MySQL database:
Code
import xml.etree.ElementTree as ET import mysql.connector # Parse the XML file xml_file = "ACNV_V03D01D_R1.xml" tree = ET.parse(xml_file) root = tree.getroot() # MySQL connection db = mysql.connector.connect( host="localhost", user="your_username", password="your_password", database="your_database" ) cursor = db.cursor() # Create tables cursor.execute(""" CREATE TABLE IF NOT EXISTS Product ( id VARCHAR(255) PRIMARY KEY, name VARCHAR(255), version INT, singlecontent BOOLEAN ) """) cursor.execute(""" CREATE TABLE IF NOT EXISTS Volume ( id VARCHAR(255) PRIMARY KEY, product_id VARCHAR(255), name VARCHAR(255), number INT, sourcefiletype VARCHAR(50), preview_discid VARCHAR(255), preview_suffix VARCHAR(10), preview_installdir VARCHAR(255), preview_path_on_disc VARCHAR(255), preview_thumbnail_suffix VARCHAR(10), install_size_img INT, install_size_img_mov INT, total_preview_size INT, total_source_size FLOAT, base_j3_version VARCHAR(255), FOREIGN KEY (product_id) REFERENCES Product(id) ) """) cursor.execute(""" CREATE TABLE IF NOT EXISTS Disc ( id VARCHAR(255) PRIMARY KEY, volume_id VARCHAR(255), number INT, FOREIGN KEY (volume_id) REFERENCES Volume(id) ) """) cursor.execute(""" CREATE TABLE IF NOT EXISTS Content ( id VARCHAR(255) PRIMARY KEY, disc_id VARCHAR(255), type INT, name VARCHAR(255), originalfps INT, frames INT, description VARCHAR(255), resolution VARCHAR(50), resx INT, resy INT, base VARCHAR(255), keywords TEXT, FOREIGN KEY (disc_id) REFERENCES Disc(id) ) """) # Extract and insert Product product = root.attrib product_id = product["id"] cursor.execute(""" INSERT INTO Product (id, name, version, singlecontent) VALUES (%s, %s, %s, %s) ON DUPLICATE KEY UPDATE name=VALUES(name), version=VALUES(version), singlecontent=VALUES(singlecontent) """, (product["id"], product["name"], int(product["version"]), product["singlecontent"] == "true")) # Extract and insert Volume for volume in root.findall("volume"): volume_attrib = volume.attrib cursor.execute(""" INSERT INTO Volume (id, product_id, name, number, sourcefiletype, preview_discid, preview_suffix, preview_installdir, preview_path_on_disc, preview_thumbnail_suffix, install_size_img, install_size_img_mov, total_preview_size, total_source_size, base_j3_version) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) ON DUPLICATE KEY UPDATE name=VALUES(name), number=VALUES(number), sourcefiletype=VALUES(sourcefiletype), preview_discid=VALUES(preview_discid), preview_suffix=VALUES(preview_suffix), preview_installdir=VALUES(preview_installdir), preview_path_on_disc=VALUES(preview_path_on_disc), preview_thumbnail_suffix=VALUES(preview_thumbnail_suffix), install_size_img=VALUES(install_size_img), install_size_img_mov=VALUES(install_size_img_mov), total_preview_size=VALUES(total_preview_size), total_source_size=VALUES(total_source_size), base_j3_version=VALUES(base_j3_version) """, (volume_attrib["id"], product_id, volume_attrib["name"], int(volume_attrib["number"]), volume_attrib["sourcefiletype"], volume_attrib["preview_discid"], volume_attrib["preview_suffix"], volume_attrib["preview_install_dir"], volume_attrib["preview_path_on_disc"], volume_attrib["preview_thumbnail_suffix"], int(volume_attrib["install_size_img"]), int(volume_attrib["install_size_img_mov"]), int(volume_attrib["totalPreviewSize"]), float(volume_attrib["totalSourceSize"]), volume_attrib["baseJ3Version"])) # Extract and insert Disc for disc in volume.findall("disc"): disc_attrib = disc.attrib cursor.execute(""" INSERT INTO Disc (id, volume_id, number) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE volume_id=VALUES(volume_id), number=VALUES(number) """, (disc_attrib["id"], volume_attrib["id"], int(disc_attrib["number"]))) # Extract and insert Content for content in disc.findall(".//content"): content_attrib = content.attrib keywords = content.find("keywords").text if content.find("keywords") is not None else "" cursor.execute(""" INSERT INTO Content (id, disc_id, type, name, originalfps, frames, description, resolution, resx, resy, base, keywords) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) ON DUPLICATE KEY UPDATE type=VALUES(type), name=VALUES(name), originalfps=VALUES(originalfps), frames=VALUES(frames), description=VALUES(description), resolution=VALUES(resolution), resx=VALUES(resx), resy=VALUES(resy), base=VALUES(base), keywords=VALUES(keywords) """, (content_attrib["id"], disc_attrib["id"], int(content_attrib["type"]), content_attrib.get("name", ""), int(content_attrib["originalfps"]), int(content_attrib["frames"]), content_attrib["description"], content_attrib["resolution"], int(content_attrib["resx"]), int(content_attrib["resy"]), content_attrib.get("base", ""), keywords)) # Commit and close db.commit() cursor.close() db.close() print("Data successfully loaded into MySQL!")
Steps:
- Install Dependencies: Ensure
mysql-connector-python
is installed:bashCopy codepip install mysql-connector-python
- Create MySQL Database: Replace placeholders (
your_username
,your_password
,your_database
) with actual database credentials. - Run the Script: Save the XML file as
ACNV_V03D01D_R1.xml
in the script’s directory and execute the Python script. It will parse the XML, create tables if they don’t exist, and load the data.
This approach ensures deduplication using ON DUPLICATE KEY UPDATE
and maintains referential integrity via foreign keys.
I’m now given python code which I can test
Testing my new data load process
For simplicity I’ll do it all on a local machine, also I’m not focusing on security here.
Creating the database & user
Again, this can be simplified by AI (this time I used Gemini from Google) asking:
generate MySQL sql to create a database called xml_loader_example, and grant all access to it to a new user called xml_loader_example_user
-- Create the database CREATE DATABASE IF NOT EXISTS xml_loader_example; -- Create the user (if it doesn't already exist) CREATE USER IF NOT EXISTS 'xml_loader_example_user'@'%' IDENTIFIED BY 'some_strong_password'; -- Replace with a real password! -- Grant all privileges on the database to the user GRANT ALL PRIVILEGES ON xml_loader_example.* TO 'xml_loader_example_user'@'%'; -- Flush privileges to ensure the changes take effect FLUSH PRIVILEGES;
Setting up the virtual environemnt
I’m using Linux, if you don’t know about a virtual environment, check out the python venv documentation.
# Create the virtual environment python -m venv venv # Activate it source venv/bin/activate # Update pip (always good practice with a new virtual environment) pip install --upgrade pip
Install the dependencies as suggested by ChatGPT
pip install mysql-connector-python
Modify the code to contain the database credentials
# MySQL connection db = mysql.connector.connect( host="localhost", user="xml_loader_example_user", password="some_strong_password", database="xml_loader_example" )
And now the magic moment, does it work?
python xml_loader.py Data successfully loaded into MySQL!
My first thought was “Wow, that was fast… There were no errors, Did it work first time without any issues?”
Test it in MySQL
Again, I asked ChatGPT to create the SQL I wanted.
generate SQL to show content ID and description, disc ID, volume name and product name
SELECT c.id AS content_id, c.description AS content_description, d.id AS disc_id, v.name AS volume_name, p.name AS product_name FROM Content c INNER JOIN Disc d ON c.disc_id = d.id INNER JOIN Volume v ON d.volume_id = v.id INNER JOIN Product p ON v.product_id = p.id;
Here is the output (with the help of tableconvert.com to quickly format for the blog post):
content_id | content_description | disc_id | volume_name | product_name |
---|---|---|---|---|
All Star_HD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
All Star_SD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Amber Rays_HD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Amber Rays_SD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Approaching Doom_HD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Approaching Doom_SD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Balloon Rise_HD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Balloon Rise_SD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Blending Pipes_HD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Blending Pipes_SD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Bundle Of Joy_HD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Bundle Of Joy_SD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Center Of Attention_HD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Center Of Attention_SD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Cloud Interference_HD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Cloud Interference_SD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Coin Collection_HD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Coin Collection_SD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Dazzling Moonlight_HD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Dazzling Moonlight_SD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Diagonal Slide_HD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Diagonal Slide_SD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Different Positions_HD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Different Positions_SD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Firefly Goodbye_HD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Firefly Goodbye_SD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Fitting Frames_HD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Fitting Frames_SD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Flying Colors_HD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Flying Colors_SD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Frame Impression_HD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Frame Impression_SD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
French Parade_HD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
French Parade_SD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Garden Whispers_HD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Garden Whispers_SD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Happy Summer_HD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Happy Summer_SD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Heavenly Beam_HD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Heavenly Beam_SD | Animated Background | ACNV_V03D01D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Hiding Magic_HD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Hiding Magic_SD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Higher Than The Sky_HD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Higher Than The Sky_SD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Hue Progression_HD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Hue Progression_SD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
I Put A Spell On You_HD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
I Put A Spell On You_SD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Magic Unleashed_HD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Magic Unleashed_SD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Restricted Area_HD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Restricted Area_SD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Sahara Evenings_HD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Sahara Evenings_SD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Sea Outside_HD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Sea Outside_SD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Searchlights_HD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Searchlights_SD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Sharp Stops_HD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Sharp Stops_SD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Shifting Midnight_HD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Shifting Midnight_SD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Slowly Spreading_HD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Slowly Spreading_SD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Smooth Ripples_HD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Smooth Ripples_SD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Soul Of Sin_HD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Soul Of Sin_SD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Square Resolution_HD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Square Resolution_SD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Star Attraction_HD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Star Attraction_SD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Start The Party_HD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Start The Party_SD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Strange Divisions_HD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Strange Divisions_SD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Stripe Intentions_HD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Stripe Intentions_SD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Suburban Summer_HD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Suburban Summer_SD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Surprising Revelation_HD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Surprising Revelation_SD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Tricky Footing_HD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Tricky Footing_SD | Animated Background | ACNV_V03D02D_R1 | Animated Canvases Collection 3 | Animated Canvases |
Final thoughts
The solution was generated in a matter of minutes, something which would probably take a developer who doesn’t use python regularly a lot longer to write and debug. As a data professional, learning to use AI to support our development processes will enable us to be far more efficient.
There are other approaches I could have taken, this is a very ETL (Extract Transform Load) approach, rather than an ELT (Extract Load Transform) approach of loading the XML into the database and using XML parsing there to extract the required data.
One thing I didn’t include in the sample above was iterating over files (it only loads the one file). Of course, to iterate over multiple files I just had to ask:
modify the python code to iterate over XML files in a directory
Security, governance & good practice
- Don’t trust anything generated by AI without reading/checking it first, it can make mistakes.
- Don’t share sensitive company information/data with an AI platform.
- Changes will have to be made to the code/database for security/limiting access (including not sticking with the default password suggested by Gemini).
Tools which do this for us
As a side note, If we just had one small simple file to load, then there are some online tools which I’d recommend developers have a play with. They use AI and general logic approaches to parse files and generate the content in SQL: