The Wayback Machine - https://web.archive.org/web/20201115062833/https://github.com/knex/knex/issues/3850
Skip to content
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

Feature Request: .mjs (es module) migrations and seeds (no cli) #3850

Open
JasonWoof opened this issue May 10, 2020 · 3 comments
Open

Feature Request: .mjs (es module) migrations and seeds (no cli) #3850

JasonWoof opened this issue May 10, 2020 · 3 comments

Comments

@JasonWoof
Copy link

@JasonWoof JasonWoof commented May 10, 2020

Environment

Knex version: 0.21.1
OS: docker node:latest

I'd like to be able to write my migrations (and seed) files as es modules with the .mjs file extension like I'm doing with all my other javascript files.

I'd like to be able to run these migrations from within node (not via the cli) like this:

db/migrations/00001-users-table.mjs:
    export const up = knex => knex.schema.createTable('users'...
    export const down = knex => knex.schema.dropTable('users');

index.mjs:
    import knex from 'knex';
    const db = app.context.db = knex({client: ..., connection: {...}});
    db.migrate.latest({
        extension: 'mjs',
        directory: 'db/migrations'),
    });

Ditto for seed files.

Thanks!

@D10221
Copy link
Contributor

@D10221 D10221 commented Aug 23, 2020

Sorry if I'm missing something :)
But it works today

import knex from 'knex';
// const db = app.context.db = knex({ client: "sqlite", connection: "./knex-mjs.sqlite" });
const db = knex({
    client: "sqlite3",
    connection: {
        filename: "./knex-mjs.sqlite"
    },
   migrations: {  // important! 
        loadExtensions: [".mjs"],
    },
    useNullAsDefault: true
});
db.migrate.latest({
    extension: 'mjs',
    directory: 'db/migrations',
}).then(() => {
    console.log("done")
    process.exit()
}).catch(e => {
    console.error(e);
    process.exit(1)
})
$node --version
v14.8.0
$node index.mjs
FS-related option specified for migration configuration. This resets migrationSource to default FsMigrations      
done
$cat package.json
{
  "name": "knex-esm",
  "dependencies": {
    "knex": "^0.21.5",
    "sqlite3": "^5.0.0"
  },
  "scripts": {
    "knex": "knex"
  }
}
$cat db/migrations/one.mjs
/**
 * @param {import("knex")} knex
 */
export function up(knex) {
    return knex.schema.createTable('xyz', (table) => {
        table.string('name');
    });
}
/**
 * @param {import("knex")} knex
 */
export function down(knex) {
    return knex.schema.dropTable('xyz');
}
$rm knex-mjs.sqlite && node index.mjs && sqlite3 knex-mjs.sqlite "select name from sqlite_master"
FS-related option specified for migration configuration. This resets migrationSource to default FsMigrations
FS-related option specified for migration configuration. This resets migrationSource to default FsMigrations
FS-related option specified for migration configuration. This resets migrationSource to default FsMigrations
done
knex_migrations
sqlite_sequence
knex_migrations_lock
xyz
$
@JasonWoof
Copy link
Author

@JasonWoof JasonWoof commented Aug 24, 2020

Thanks! I didn't realize I had to specify the extension of my migration files twice... or maybe the "extension:" key is not needed?

I find it really strange that the extension: configuration key to migrate.latest() doesn't configure it to use migrations with that extension.

I suggest either:

  1. The extension: config sets that extension for both reading and writing migration files (so my example could would work as-is).

or

  1. A note is added to the docs for extension:' key here http://knexjs.org/#Migrations-API cautioning that this config isn't used when reading migration files and that you need to use loadExtensions:` for that.
@D10221
Copy link
Contributor

@D10221 D10221 commented Aug 24, 2020

Yes, Its not very intuitive, I think.
Tracking the 'extension' property by usage, Seems to be used to generate stubs only.
There is a note, now, in the docs, on the 'esm' section , where it mentions 'loadExtension', specifically for 'mjs' files.
You have to be explicit because is not on the default file extension list.
While is esm related, mjs is part of the current/standard NodeJs module resolution,
perhaps it should be added to default list of well known extensions ?
And maybe a jsdoc entry in the type definition ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.