Hakeem Gaines moved his app to a new database in September. Over two days, Sept. 4 and 5, he moved the data and proved the move worked25.
The app is Trainspotting, an archive of fashion designers and the collections they made4. Gaines built it in Zip Code Wilmington's data cohort, as a passion project. Its data lived in SQLite, a database that keeps everything in one file. He moved it to MySQL, a database server built for many users at once3.
AI helped him write the code. He leaned on OpenAI's Codex most, he told AI Lately1. His proof came from checks he designed himself: row counts, content fingerprints and a timed restore25.
"It can't choose the acceptable risk. It can't prove that the migration was correct. That's ultimately up to the engineer to resolve," Gaines said1.
He walks through the work at PumpCon in Philadelphia on Saturday, Oct. 248. It is his first technical talk1.
A Fashion Archive Built to Learn
Trainspotting began in August 2026 as homework on one-to-many relationships112. That database idea means one designer can have many collections. Gaines had already built a library system for books, movies and CDs. He swapped in fashion because he cares about it.
"When you have a personal interest in something, it just makes it a little easier to learn new things, I find," Gaines said1.
That interest started at home. An older brother loved clothes and basketball, and Gaines followed him into Polo and Jordans as a kid1. Today he follows designers more than labels. A designer can work for Louis Vuitton for a few seasons, then Gucci, then Loewe, and Trainspotting tracks those moves.
The name began as a pun. Gaines pictured a future model that would find patterns in the collections users save.
"I'd be able to spot trends among the things that the users like. And I was thinking I'd be kind of like trendspotting," Gaines said1.
Trendspotting became Trainspotting, a nod to the cult film, set against luxury clothing1. The look came from his own brief to his AI assistant. It named public broadcasting, the label Telfar and the designer Shane Oliver, plus CRT scanlines and terminal loading screens.
"I have no desire to do things the same way that everyone else does them," Gaines said1.

Why SQLite Ran Out of Room
SQLite suited the first version, a read-only archive on one computer3. Version two changed the job.
Members now sign in with Clerk, submit designers and collections, and wait for moderation34. Each decision lands in an audit history that can roll back a bad edit. Gaines deployed the app on Railway, a hosting service, as separate web, API, database and backup services2.
Many writers at once was the problem. SQLite allows only one write transaction at a time, which can become a constraint as concurrent writes increase2.
"SQLite was effective for the small, simple project that I had in mind initially," Gaines said1.
His decision record, dated Sept. 4, picks MySQL 8.4, with SQLAlchemy as the layer between the app and the database3. It lists five options he rejected, from a straight driver swap to writing to both databases during the move. Halfway through, he weighed PostgreSQL and kept MySQL to finish one clean migration1.
"Dual writes would create two authorities and introduce reconciliation failure modes that the current project does not need," Gaines's decision record says3.
The Connection String Was Only the Start
Gaines expected an easy switch. SQLAlchemy is a Python library that talks to many databases through one interface. He thought one setting, the database URL, would do the job1.
It took more. His code still used SQLite's placeholders, transaction commands, row access, collation syntax and locking2.
"SQLAlchemy could help with the portable connections and statements, but it could not reinterpret like every SQLite-specific decision that had already embedded into the code," Gaines said1.
So he wrote a compatibility layer, one file that translates each old query on its way to MySQL12. A question mark in the old SQL becomes a named slot, such as :p0. The values travel in a matching dictionary. In one exchange he shared, Codex corrected his first try: the colon belongs in the SQL, and the dictionary keys drop it.

Locking changed too. On MySQL, Trainspotting uses SELECT ... FOR UPDATE inside an explicit transaction to lock the records involved in a moderation decision2.

How He Knew the Data Survived
Gaines calls that question the center of his story. "It changed how I think about the difference between code running successfully and data actually being preserved," he wrote to AI Lately12.
Moving the rows took its own program. Alembic, a schema tool, built the empty MySQL tables. A separate transfer script carried the rows2.
That script follows strict rules2. It opens SQLite read-only. A MySQL target that holds any data gets refused. Parent rows go first, so each collection arrives after its designer, and every original ID stays the same.
Then it checks its own work. For every table, it compares the row count and a SHA-256 digest, a fingerprint computed from the sorted, normalized rows2. Matching counts show the rows arrived. Equal fingerprints show that the ordered, normalized row content included in the digest matched.
The script moved nine tables on Sept. 4, and the checkpoint highlights five of them212. They held 46 designers, 373 collections, 415 media records, 2 submissions and 8 audit events. That is 844 rows, with zero count mismatches and zero digest mismatches.
All 844 rows in five highlighted tables matched between SQLite and MySQL in Hakeem Gaines's migration
Rows per table in the SQLite source and the MySQL target, Trainspotting's Sept. 4, 2026 checkpoint
Each row is one table. A blue dot marks the source count and a magenta dot the target count; where they match, the magenta dot covers the blue.
The Sept. 4 slide highlights five of the nine migrated tables. Matching SHA-256 digests showed that the ordered, normalized row content in each digest matched, as well as the counts.
Source: Hakeem Gaines (talk slides) [2]. Chart by Ryan Elliott Dennis.
The numbers behind this chart
| Item | SQLite source rows | MySQL target rows |
|---|---|---|
| Collection media | 415 | 415 |
| Collections | 373 | 373 |
| Designers | 46 | 46 |
| Audit events | 8 | 8 |
| Submissions | 2 | 2 |
A day later he tested the backup side. The schema had kept evolving by then12. On Sept. 5, he restored an encrypted backup into an empty, separate database5. The drill verified the then-current 11-table database and four audit-protection triggers in under five minutes.
844 rows in five highlighted tables matched on Sept. 4, and a day later the restore drill verified all 11 tables then in the schema
Rows copied per table on Sept. 4, 2026, then the restore drill on Sept. 5, 2026
Each cube is one row. Rows leave the SQLite file in dependency order, parents first, and stack in their table; a table turns magenta once its count matches. The Sept. 4 visual highlights five of the nine migrated tables. The next day, after the schema had kept evolving, the restore drill verified the then-current 11-table database and four audit-protection triggers, in under five minutes.
Sources: Hakeem Gaines (talk slides) [2]; GitHub [5]. Figure by Ryan Elliott Dennis.
The numbers behind this figure
| Table | Rows copied and matched |
|---|---|
| Designers, Sept. 4 | 46 |
| Collections, Sept. 4 | 373 |
| Collection media, Sept. 4 | 415 |
| Submissions, Sept. 4 | 2 |
| Audit events, Sept. 4 | 8 |
| Restore drill, Sept. 5 | 11 tables and 4 audit triggers, under 5 minutes |
Gaines keeps the limits in writing. His backup guide calls the five minutes "drill evidence, not yet the production recovery-time objective"5. The slides list what the digests left unproven: indexes, constraints, triggers, collation, concurrency, app workflows and restoration2.

One check did fail. On Railway, two services could start at once and race to apply the same schema change1. Unless that transaction committed explicitly, Gaines said, "the migration could appear to run while the revision ledger did not persist". He fixed the deployment and shipped it again.
Where AI Helped, and Where It Stopped
Gaines gives AI real credit. It explained unfamiliar errors, drafted options and sped him through SQLAlchemy and Alembic1.
"AI ultimately made the work faster. It expanded what I could investigate," Gaines said1.
He prefers Codex to Claude Code and GitHub Copilot, because it follows his instructions closely1.
"I need it to do exactly what I'm asking it to do," Gaines said1.
His archive writes the same rule into code. Trainspotting's recommendation feature runs on visible rules, and its test file bans one inference outright. In a Pyer Moss record, the file says, "Black describes cultural identity and history in this record, not garment color"6. His image policy draws a similar line: "A factual citation does not license the photograph"7.
Two outside voices frame the larger debate. Sundar Pichai, chief executive of Google, describes AI code that people check before it ships.
"Today, more than a quarter of all new code at Google is generated by AI, then reviewed and accepted by engineers. This helps our engineers do more and move faster," Pichai said in October 20249.
Jens Wessling, chief technology officer at Veracode, reads the evidence the other way. His firm tested more than 100 models on 80 coding tasks10. In 45 percent of test cases, the models added a flaw from the OWASP Top 10. That list ranks the most critical web security risks.
"Our research reveals GenAI models make the wrong choices nearly half the time, and it's not improving," Wessling said10.
Language models added a security flaw in 45% of Veracode's coding tests
Share of test cases with an OWASP Top 10 flaw, 80 coding tasks across more than 100 models, 2025
The magenta arc is the share of test cases where a model's code carried one of the ten most critical web security risks.
Source: Veracode [10]. Chart by Ryan Elliott Dennis.
The numbers behind this chart
| Item | Value |
|---|---|
| Test cases with a flaw | 45% |
| Whole | 100% |
A lab study adds a second caution. METR timed 16 experienced developers on 246 real tasks in early 202511. With AI tools, they took 19 percent longer. They had expected to finish 24 percent faster, and afterward they still believed AI had sped them up by 20 percent.
Gaines put the lesson on one slide: "'The application starts,' 'the tests pass,' and 'the data survived' are different claims"2.
From Project Manager to Engineer
Gaines came to code from project management. He spent more than eight years coordinating technical projects and teaching IT and project management, he says12. By his own count, his projects landed on time 98 percent of the time, across more than 50 active milestones. Adult learners in his classes passed certification exams at a 92 percent rate, he says.
"That background shapes how I approach engineering: understand the requirements, validate the data, document decisions, test the system, and deliver something people can confidently use," Gaines wrote12.
He grew up in Wilmington, Delaware, and studied at Howard University in Washington1. After about a decade in Washington and a couple of years in Chicago, he moved home.
Back in Delaware, he finished a data engineering and analytics program of more than 1,000 hours at Zip Code Wilmington12. His other projects include a city-planning platform built on PySpark and PostgreSQL, and a historical banking system that spots unusual records.

"It's something that I did to help me learn," Gaines said of Trainspotting1.
The talk grew out of another conference. At DevOps Philadelphia, speakers he met at their dinner urged him to pitch the migration to PumpCon1.
"This is my first time having a technical talk," Gaines said1.
The talk also gives him a chance to demonstrate his engineering decisions to prospective employers12. He wants data engineering work on reliable pipelines, analytics systems and data-backed products.
What to Do
Moving data with an AI assistant? Borrow Gaines's proof along with his tools. Count the rows in every table on both sides, and compare a fingerprint of each table's sorted contents2. Then restore a backup into an empty database and time it5.
Write down what your checks leave unproven, the way his slides do2. A list of the gaps tells your team where the next test belongs. Keep a decision record too, with the options you rejected and why3.
What to Watch
PumpCon runs talks from noon to 5 p.m. on Saturday, Oct. 24, in Philadelphia8. The event bans recording, so the room is the one place to hear the full version.
Trainspotting's next test is traffic. The decision record names concurrent member writes and background ingestion as the reasons for MySQL3. More members would show whether the new database earns that choice.
Each side of the debate needs its own evidence. Pichai's case needs reviewed AI code to hold up in production9. Wessling's needs the flaw rate to stay near 45 percent as models improve10.
Sources
- Ryan Elliott Dennis, "Interview with Hakeem Gaines," AI Lately, Oct. 16, 2026
- Hakeem Gaines, "It Worked on SQLite: Migrating a real app to MySQL with SQLAlchemy and AI (talk slides, draft)," Hakeem Gaines (talk slides), Oct. 16, 2026
- Hakeem Gaines, "ADR 0001: MySQL as the production database," GitHub, Sept. 4, 2026, https://github.com/Hgaines88/Trainspotting/blob/main/docs/adr/0001-mysql-production-database.md
- Hakeem Gaines, "Trainspotting repository," GitHub, Sept. 30, 2026, https://github.com/Hgaines88/Trainspotting
- Hakeem Gaines, "Backup and restore," GitHub, Sept. 5, 2026, https://github.com/Hgaines88/Trainspotting/blob/main/docs/BACKUP_AND_RESTORE.md
- Hakeem Gaines, "Recommendation evaluation cases," GitHub, Sept. 30, 2026, https://github.com/Hgaines88/Trainspotting/blob/main/docs/recommendation-evaluation.json
- Hakeem Gaines, "Archive image strategy decision," GitHub, Sept. 30, 2026, https://github.com/Hgaines88/Trainspotting/blob/main/docs/IMAGE_STRATEGY_DECISION.md
- PumpCon, "Pumpcon 2026," PumpCon, Oct. 16, 2026, https://www.pumpcon.lol
- Sundar Pichai, "Message from our CEO: Alphabet Q3 2024 earnings," Google, Oct. 29, 2024, https://blog.google/inside-google/message-ceo/alphabet-earnings-q3-2024/
- Veracode, "AI-Generated Code Poses Major Security Risks in Nearly Half of All Development Tasks, Veracode Research Reveals," Veracode, July 30, 2025, https://www.veracode.com/press-release/ai-generated-code-poses-major-security-risks-in-nearly-half-of-all-development-tasks-veracode-research-reveals/
- METR, "Measuring the Impact of Early-2025 AI on Experienced Open-Source Developer Productivity," METR, July 10, 2025, https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/
- Hakeem Gaines, "Professional background and messages, shared with AI Lately with his consent," Hakeem Gaines, Oct. 16, 2026


