TL;DR: Need to write complex Prisma migrations (renaming, splitting, merging models)? Instead of writing SQL by hand:
- Save your old schema
- Make changes in
schema.prisma
- Run prisma migrate dev --create-only
- Let GenAI handle the SQL data transformations
Been using this approach while building Stems - saved hours on migrations while preserving data and relationships. Works great for anything from simple renames to complex model splits.
While building Stems, I needed to split our monolithic Track model into three separate models: OfficialTrack, Stem, and Remix. This better represented our domain - official tracks have stems, which users can download to create remixes. Here's how I handled this data model evolution using GenAI to save time on SQL migrations.
The change involved rougly the following:
// Before: Everything in one model
model Track {
id String @id
title String
artist String
previewPath String?
stemPaths String[] // All stems stored here
isRemix Boolean
parentTrack Track? @relation("RemixOf")
remixes Track[] @relation("RemixOf")
}
// After: Split into domain-specific models
model OfficialTrack {
id String @id
title String
artist String
stems Stem[]
remixes Remix[]
}
model Stem {
id String @id
title String // e.g., "vocals", "drums"
audioUrl String
track OfficialTrack @relation(fields: [trackId], references: [id])
trackId String
}
model Remix {
id String @id
title String
artist String
audioUrl String
original OfficialTrack @relation(fields: [trackId], references: [id])
trackId String
}
Instead of manually writing the data migration, here's what worked:
- Save the current schema:
cp schema.prisma schema-old.prisma
- Update schema.prisma with the new models
- Generate migration scaffold:
npx prisma migrate dev --create-only
- Prompt for AI assistance:
I'm splitting the Track model into OfficialTrack, Stem, and Remix models.
schema-old.prisma has the original Track model where:
- Non-remix tracks (isRemix=false) should become OfficialTrack records
- stemPaths array should be split into individual Stem records
- Remix tracks (isRemix=true) should become Remix records
- All relationships need to be preserved Please modify the SQL migration to handle this data transformation.
- Review the generated SQL carefully - this kind of split is complex enough that you might need to tweak the migration or ask for adjustments
Key learnings:
- This approach works best when you can clearly describe the transformation rules
- For complex splits like this, I always test the migration on a copy of production data first
- Breaking down the migration into smaller steps (create new tables → migrate data → update relationships → drop old table) made it easier to verify correctness
- Having the old schema file is crucial for AI to understand the full context This method significantly reduced the time I would've spent writing and debugging SQL migrations, though I still needed to review and test thoroughly given the complexity of the model split.
Top comments (1)
This is quite interesting approach, thanks for sharing