惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
Project Zero
Project Zero
博客园 - 聂微东
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
云风的 BLOG
云风的 BLOG
Microsoft Azure Blog
Microsoft Azure Blog
F
Fortinet All Blogs
Martin Fowler
Martin Fowler
Jina AI
Jina AI
C
Check Point Blog
博客园_首页
The GitHub Blog
The GitHub Blog
The Hacker News
The Hacker News
T
The Blog of Author Tim Ferriss
V
Vulnerabilities – Threatpost
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cisco Blogs
人人都是产品经理
人人都是产品经理
V
Visual Studio Blog
A
Arctic Wolf
博客园 - 三生石上(FineUI控件)
P
Privacy International News Feed
Application and Cybersecurity Blog
Application and Cybersecurity Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Forbes - Security
Forbes - Security
阮一峰的网络日志
阮一峰的网络日志
Engineering at Meta
Engineering at Meta
T
Troy Hunt's Blog
Microsoft Security Blog
Microsoft Security Blog
Spread Privacy
Spread Privacy
Schneier on Security
Schneier on Security
K
Kaspersky official blog
宝玉的分享
宝玉的分享
Google DeepMind News
Google DeepMind News
V2EX - 技术
V2EX - 技术
Google DeepMind News
Google DeepMind News
AWS News Blog
AWS News Blog
Know Your Adversary
Know Your Adversary
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Y
Y Combinator Blog
大猫的无限游戏
大猫的无限游戏
S
Security Affairs
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - Franky
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
The Register - Security
The Register - Security
P
Proofpoint News Feed
小众软件
小众软件
S
Securelist
T
Tor Project blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Running a Real Retail Dataset Through a Python Data Quality Workflow
Bob Oner · 2026-06-16 · via DEV Community

In the previous article, I extended a small Python data quality ETL starter with AI-ready data preparation.

The important constraint was that the workflow did not call an LLM API, generate embeddings, or train a model. It prepared structured data assets such as schema profiles, data dictionaries, validation summaries, feature-ready CSV files, and manifest files.

Previous article:

Preparing AI-Ready Data Without Calling an LLM API

This follow-up focuses on the v0.7.0 update of the same project:

Data Quality ETL Starter on GitHub

The new goal is to move beyond synthetic demo data and show that the same data quality workflow can process a public retail/e-commerce-style dataset locally.

This is still not a big data platform, a production retail analytics system, a benchmark leaderboard, or a public dataset redistribution repository.

The goal is narrower and more practical:

manually downloaded public retail dataset
        ↓
prepare_real_dataset_demo.py
        ↓
normalized retail transaction CSV
        ↓
existing CLI validation and cleaning workflow
        ↓
quality reports + SQLite export
        ↓
run_real_dataset_benchmark.py
        ↓
benchmark report + summary CSV outputs

That is a useful next step for a portfolio project because it shows the workflow can handle a more realistic dataset while still keeping data handling, scope, and reproducibility clear.

Why add a real dataset benchmark?

Earlier versions of this project used small sample files and generated synthetic order data.

That is useful for testing and documentation, but it leaves one practical question:

Can the workflow handle a public dataset that was not designed specifically for this repository?

v0.7.0 adds an optional real dataset benchmark path to answer that question.

The workflow now demonstrates how to:

  • take a public retail transaction dataset;
  • keep the raw dataset local-only;
  • map external source columns into a project-friendly schema;
  • derive practical fields such as revenue and cancellation flags;
  • reuse the existing CLI validation and cleaning workflow;
  • generate Markdown and JSON quality reports;
  • export cleaned data to SQLite;
  • produce benchmark evidence and summary CSV files.

The key design choice is that the existing CLI remains the source of truth.

The real dataset path does not become a separate pipeline. It prepares the source data, then passes it through the same validation and cleaning workflow used by the rest of the project.

Dataset used in v0.7.0

The default v0.7.0 dataset is the UCI Online Retail dataset.

Official source:

UCI Machine Learning Repository: Online Retail

Citation:

Chen, D. (2015). Online Retail [Dataset]. UCI Machine Learning Repository.
https://doi.org/10.24432/C5BW33

License note:

Creative Commons Attribution 4.0 International (CC BY 4.0)

The dataset is useful for this project because it is retail/e-commerce adjacent and transaction-shaped. It includes fields that map naturally into an invoice/order-style workflow:

InvoiceNo
StockCode
Description
Quantity
InvoiceDate
UnitPrice
CustomerID
Country

The project maps those source columns into normalized snake_case columns and adds derived fields.

What is kept out of Git

This part is important.

The repository does not redistribute the full raw UCI dataset. It also does not commit full normalized or cleaned real dataset outputs.

These paths are local-only:

data/external/
data/raw/public/
data/output/real_dataset/

The repository keeps:

  • source code;
  • schema files;
  • tests;
  • documentation;
  • screenshots;
  • small sample inputs;
  • instructions for running the workflow locally.

It does not keep:

  • full downloaded raw datasets;
  • full normalized real dataset outputs;
  • full cleaned real dataset outputs;
  • local SQLite files generated from real datasets;
  • private customer data;
  • client data;
  • API credentials;
  • tokens or secrets.

This keeps the repository lightweight and avoids turning it into a dataset mirror.

Real dataset source and redistribution note

What v0.7.0 adds

The most relevant new files are:

scripts/prepare_real_dataset_demo.py
scripts/run_real_dataset_benchmark.py
src/dq_etl_starter/real_dataset.py
docs/data_sources.md
docs/real_dataset_benchmark.md
docs/limitations.md
data/expected/online_retail_schema.json

The real dataset helper module handles the project-specific mapping and summary logic.

The two scripts provide a simple local workflow:

  1. prepare the manually downloaded dataset into a normalized CSV;
  2. generate local benchmark evidence and summary outputs after the CLI quality workflow runs.

Project structure after the update

The project now has a clearer path from messy input files to public-dataset benchmark evidence:

data-quality-etl-starter/
├── data/
│   ├── expected/
│   │   └── online_retail_schema.json
│   └── output/
├── docs/
│   ├── data_sources.md
│   ├── limitations.md
│   └── real_dataset_benchmark.md
├── screenshots/
├── scripts/
│   ├── prepare_real_dataset_demo.py
│   └── run_real_dataset_benchmark.py
├── src/dq_etl_starter/
│   ├── real_dataset.py
│   ├── cli.py
│   ├── clean.py
│   ├── report.py
│   └── validate.py
└── tests/
    ├── test_real_dataset.py
    └── test_real_dataset_benchmark.py

The real dataset path is optional. The default small sample workflows remain unchanged.

Install the project locally

Clone the repository:

git clone https://github.com/OnerGit/data-quality-etl-starter.git
cd data-quality-etl-starter

Create a virtual environment:

python -m venv .venv

Activate it on macOS or Linux:

source .venv/bin/activate

Activate it on Windows PowerShell:

.venv\Scripts\activate

Install dependencies and the local package:

pip install -r requirements.txt
pip install -e .

The editable install step is useful because the project uses a src/ layout.

Step 1: Download the public dataset manually

Download the UCI Online Retail dataset from the official UCI Machine Learning Repository page.

Place the file here:

data/external/online_retail.xlsx

The project does not automatically download the dataset by default.

That is intentional.

For a public portfolio repository, I prefer to keep the data acquisition step explicit. It makes the source, license, citation, and local-only handling policy easier to review.

Step 2: Prepare the normalized dataset

Run the preparation script.

macOS / Linux:

python scripts/prepare_real_dataset_demo.py \
  --raw-input data/external/online_retail.xlsx \
  --output data/output/real_dataset/online_retail_normalized.csv

Windows PowerShell:

python scripts/prepare_real_dataset_demo.py `
  --raw-input data/external/online_retail.xlsx `
  --output data/output/real_dataset/online_retail_normalized.csv

This step reads the local source file, validates expected source columns, maps UCI columns into project-friendly names, derives additional fields, and writes a normalized CSV.

Real dataset preparation run

The normalized output columns are:

invoice_no
stock_code
description
quantity
invoice_date
unit_price
customer_id
country
revenue
is_cancellation
source_dataset

The derived fields are simple but useful:

  • revenue is derived from quantity and unit price;
  • is_cancellation marks cancellation-style rows;
  • source_dataset records dataset lineage.

This preparation layer is deliberately small. It does not try to perform all business logic. It only converts the external dataset into a shape that the existing project workflow can validate and clean.

Step 3: Run the existing CLI workflow

After preparation, the normalized CSV is passed into the existing CLI workflow.

macOS / Linux:

python -m dq_etl_starter.cli run \
  --input data/output/real_dataset/online_retail_normalized.csv \
  --input-type csv \
  --schema data/expected/online_retail_schema.json \
  --output-dir data/output/real_dataset/run \
  --db-target sqlite \
  --table-name cleaned_online_retail

Windows PowerShell:

python -m dq_etl_starter.cli run `
  --input data/output/real_dataset/online_retail_normalized.csv `
  --input-type csv `
  --schema data/expected/online_retail_schema.json `
  --output-dir data/output/real_dataset/run `
  --db-target sqlite `
  --table-name cleaned_online_retail

Expected local outputs:

data/output/real_dataset/run/cleaned_online_retail.csv
data/output/real_dataset/run/etl_output.sqlite
data/output/real_dataset/run/quality_report.md
data/output/real_dataset/run/quality_report.json

Existing CLI workflow running against normalized real dataset

This is the most important design point in v0.7.0.

The real dataset path reuses the existing validation and cleaning workflow. It does not create a special one-off script that bypasses the project architecture.

Schema for the normalized retail dataset

The schema file is:

data/expected/online_retail_schema.json

It defines the expected normalized columns and validation rules for fields such as invoice number, stock code, quantity, invoice date, unit price, customer ID, country, revenue, cancellation flag, and source dataset.

The schema is not intended to certify the dataset as business-ready.

It is a practical contract for this starter workflow:

external retail columns
        ↓
normalized project columns
        ↓
expected schema rules
        ↓
quality report

That is a useful handoff pattern because the next person can inspect both the mapping and the validation report.

Quality report

The CLI workflow writes a Markdown report and a JSON report.

For the real dataset workflow, the Markdown report is written to:

data/output/real_dataset/run/quality_report.md

Real dataset quality report

The report is useful because it records what the workflow found rather than only producing a cleaned file.

Typical report sections include:

  • raw row count;
  • cleaned row count;
  • missing values by column;
  • duplicate row count;
  • expected column checks;
  • validation issue summaries;
  • output file paths.

For client-style work, this is important. A cleaned output file alone is not enough. The workflow should also explain what was detected and what still needs review.

Step 4: Generate the real dataset benchmark report

After the CLI workflow finishes, generate a local benchmark report and summary outputs.

macOS / Linux:

python scripts/run_real_dataset_benchmark.py \
  --normalized-input data/output/real_dataset/online_retail_normalized.csv \
  --quality-report data/output/real_dataset/run/quality_report.json \
  --output-dir data/output/real_dataset \
  --dataset-name uci_online_retail

Windows PowerShell:

python scripts/run_real_dataset_benchmark.py `
  --normalized-input data/output/real_dataset/online_retail_normalized.csv `
  --quality-report data/output/real_dataset/run/quality_report.json `
  --output-dir data/output/real_dataset `
  --dataset-name uci_online_retail

Expected local outputs:

data/output/real_dataset/benchmark_report.md
data/output/real_dataset/summary/revenue_by_country.csv
data/output/real_dataset/summary/revenue_by_month.csv
data/output/real_dataset/summary/cancellation_summary.csv
data/output/real_dataset/summary/missing_customer_summary.csv

Real dataset benchmark report

The benchmark report is not a universal performance claim.

It is local evidence for this machine, this dependency environment, and this dataset preparation flow.

That distinction matters. Runtime can change depending on CPU, disk speed, Python version, package versions, source file format, operating system, and local machine conditions.

Summary outputs

The benchmark script also writes lightweight summary CSV files.

Real dataset summary outputs

The summary outputs are intentionally simple:

revenue_by_country.csv
revenue_by_month.csv
cancellation_summary.csv
missing_customer_summary.csv

They are not a full BI model.

They are small reporting-ready outputs that show how a cleaned retail transaction dataset can be summarized after validation.

For example:

  • revenue_by_country.csv supports country-level revenue inspection;
  • revenue_by_month.csv supports monthly trend inspection;
  • cancellation_summary.csv records cancellation and non-positive row counters;
  • missing_customer_summary.csv helps inspect where customer IDs are missing.

This is often enough for a first data workflow milestone.

The next version could load these into PostgreSQL, query them in DuckDB, or feed a local dashboard, but v0.7.0 intentionally keeps the real dataset path focused.

What the benchmark report records

The benchmark report is designed to answer practical questions:

  • Which dataset was used?
  • Where did the normalized input come from?
  • How many rows were normalized?
  • How many rows reached the CLI quality workflow?
  • How many duplicate rows were detected?
  • How many cancellation rows were identified?
  • How many customer IDs or descriptions were missing?
  • Were invoice dates, quantities, and prices validated?
  • What files were produced?
  • What limitations apply?

That makes the run easier to review later.

It also makes the project stronger as a portfolio asset because the workflow is not only described in prose. It leaves behind files, screenshots, reports, and commands that can be inspected.

Why not automatically download the dataset?

The project could theoretically download the dataset automatically.

For this version, I chose not to do that.

Manual download keeps the workflow clearer:

  • the user sees the official source page;
  • the dataset citation remains visible;
  • the license note is explicit;
  • the repository does not redistribute the raw dataset;
  • the workflow does not depend on hidden network access;
  • local-only data handling is easier to explain.

For a small portfolio repository, this is a reasonable trade-off.

The project demonstrates how to process the dataset, not how to become a dataset distribution tool.

Tests

Run the full test suite:

python -m compileall -q src/dq_etl_starter
python -m compileall -q scripts
pytest

Run the v0.7-related tests:

pytest tests/test_real_dataset.py
pytest tests/test_real_dataset_benchmark.py

The tests focus on the reusable code paths rather than requiring the full external dataset to be committed.

That is another useful pattern for public repositories: test the transformation logic with small fixtures, and keep the large external dataset local-only.

What is intentionally out of scope?

The v0.7.0 real dataset benchmark does not add:

  • automatic dataset download;
  • raw dataset redistribution;
  • production scheduling;
  • Airflow orchestration;
  • dbt modeling;
  • Snowflake, Databricks, or PySpark;
  • production-scale retail analytics;
  • a complete BI dashboard;
  • a benchmark leaderboard;
  • machine learning training;
  • LLM calls;
  • RAG or AI agent features.

This project is still a small Python data workflow starter.

The v0.7.0 update proves a specific point: the workflow can be applied to a public retail transaction dataset locally, while keeping the data handling policy, validation steps, outputs, and limitations clear.

What I would improve next

Possible next improvements include:

  • adding a Makefile for repeated demo commands;
  • adding a smaller public fixture for faster walkthroughs;
  • adding optional DuckDB queries for the real dataset summaries;
  • adding optional PostgreSQL reporting tables for the real dataset path;
  • adding a short CI workflow for core tests;
  • improving benchmark report formatting;
  • adding more detailed data source mapping documentation;
  • adding a second public dataset only if it does not make the project too broad.

The main constraint remains the same:

Keep the project small, reproducible, inspectable, and easy to adapt.

Repository

GitHub repository:

https://github.com/OnerGit/data-quality-etl-starter

Previous article:

Preparing AI-Ready Data Without Calling an LLM API

This v0.7.0 update is a practical next step: from synthetic and generated demos to a local public retail dataset benchmark that reuses the same validation, cleaning, reporting, and handoff workflow.