Any thoughts on how to move data migrations from knex to kysely?
I've been working on shifting my code over to kysely, and it's been fantastic so far. However, I'm not entirely sure how to restructure my migrations directory into Kysely while maintaining up/down state without some manual overhead. The documentation has great advice for setting up migrations from scratch, but not as much for moving an existing project to its structure. I plan to collect all existing table data into a new initial migration, so that makes this somewhat easier. But there are still challenges. The way I see it I have 2 options:
1. Put a hacky check in the initial migration to apply its change only if one of my tables is not present.
2. Manually create the kysely migration record in existing databases to note that the initial migration has been run.
Neither of these feel satisfying to me. Is one preferred? Is there a general best practice that I'm missing becuase this isn't my area of expertise?
4 Replies
Hey 👋🏻
Libraries rarely do talk about migrating a brownfield project. A migration from Knex guide is something I've always thought about. it's only natural that most kysely users will come from knex.
Anyway, imho the best you can do is to keep knex as a dev dependency, and keep the old migration code in your codebase and state in your database.
Any new migration files, should use kysely, and should be placed in a new kysely migration folder and state saved in a kysely specific table (not the one knex used).
Alternatively, you could continue using knex for migrations only.
Oof, I don't know how much I like that solution, as useful as it might be for maintaining a long-lived project. I might recommend that if I was migrating my company over, since we have an ungodly amount of migration files built up over 7 years, as well as many customers on varying versions, necessitating that we maintain the ability to migrate from an arbitrary point.
Luckily my current project is a personal one, a discord bot that is in production, but only has 3 active databases, prod, staging, and dev. So I don't need to worry too much about database state in the wild. Which is why I was thinking those two options were best for me.
sometimes we gotta make decisions that are not perfect, but serve our bottom line best.
Totally agree. It just leaves a bit of a sour taste in my mouth to have the best solution be "leave the legacy technology that we have a better implementation for in the app, unable to be improved, but unable to be upgraded or removed"
I've never written a migration library, so I don't know the challenges involved, but I wonder why migrations tend to be predicated on an id value instead of a time/datestamp. I was thinking about that after seeing the kysely suggestion of the ISO date as the id value in the file. I feel like a standardized time value, and then maybe a way to init a migrator onto a time value for that environment, would be really useful for solving these kinds of issues (especially when tools like the old knex migrator cli would auto-generate ids for you)
It uses a common language instead of trying to find the numeric id of the old migration state and translate that onto the numeric id of the new state
I've also been wondering about ways to manage brownfield project migration directories. We have a huuuuge problem with this at my work. Small database changes for individual tickets each get their migration file. Then get dumped into a massive directory of impossible to organize code files. And this is the environment where we have to support many databases in the field with very different code versions