-
-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Run migrations programmatically #167
Comments
The new API could look like: import { createRakeDb } from "rake-db"
export const { rakeDb, defineMigration } = createRakeDb(
{ databaseURL: config.database_url },
{
baseTable: BaseTable,
},
// all same arguments as in { rakeDb } from "rake-db", but no string args
)
// importing { rakeDb } from "rake-db" is still possible! This is only an extension. then somewhere in a CLI script or in some other event handler: import { rakeDb } from "../my-rake-db"
const myhandler = () => {
await rakeDb(args)
// or possibly:
await rakeDb(args).promise // use the same return type as { rakeDb } from "rake-db"
} in migration: import { defineMigration } from "../my-rake-db"
export default defineMigration((change) => {
change(async (db) => {
await db.createTable("image", (t) => ({
id: t.integer().primaryKey(),
...t.timestamps(),
}))
})
}) The migration runner could simply check that if a migration module has a default export and that's a function, call it as That will be fully backwards-compatible with the current API, but give more flexibility. |
Also, I would like this: |
Lol wut? Dynamic is eager. It's impossible to stop surprising in our evolving ecosystem. Honestly, it's the weirdest bug I met in a long time. I'm proposing to let migrations have a default export while keeping all the rest of it unchanged: import { change } from '../dbScript';
export default change((db) => {
// ...
}) Sometimes we need multiple changes per file, in such a case let's export array of changes: import { change } from '../dbScript';
export default [
change((db, up) => {
// ...
}),
change((db, up) => {
// ...
}),
] The internal logic will check if there is a For the import { rakeDb } from '../src';
export const { change, run } = rakeDb.lazy({ ... }) To add a
How does it look to you, would it be enough?
Promise is expected to throw (reject) on error, I'll check if that is currently so. |
It's somehow related to preparing the package to run on edge infrastructure where there are no dynamic imports. They inline imports which gives that side effect in the dev version. They argue that one should never rely on module import side effects and I tend to agree with them in that.
Yeah, seems good!
Right, I actually concluded so later, too — please ignore that. |
Ready! Added Hope it will help with your setup. |
I just happened to migrate to this new API. Works great! Thanks so much. |
I am trying to use rake migrations inside a Nuxt 3 project, which is a bit unusual setup. Migrations must be loaded with dynamic
import
rather than traversing the directory (so that they get bundled withnuxt build
), but there is noimport.meta.glob
(nuxt/nuxt#22106), and the dynamicimport
is eager, meaning that the actual module is pre-loaded on app start, not whenimport
is called:Since all migrations call
change
on the module level, that means all of them are executed when simply preparing themigrations
collection:Additionally, there is no CLI subcommands support yet (nuxt/cli#62) and reusing Nuxt infrastructure from a third party runner such as
vite-node
is complicated, so I went with running migrations from an API handler instead of a CLI script. Migrations require a statically exportedchange
which is created by a single call torakeDb
on the module level. However, in this scenario the rakeDb args are not yet known on the module level: they will be only known later in runtime (as passed to API handler by the client).I actually managed to achieve what I wanted with some hacks:
the main rake file:
and the migration:
I propose to rework the migrations architecture to allow first class support of what I've done above, in particular:
I suppose this could be an extension (retaining backward compatibility) but I have not considered the specific APIs yet. Let me know if this makes sense at all?
The text was updated successfully, but these errors were encountered: