Error running sequelize seeder on typescript based setup
Asked Answered
N

2

3

I want to use sequelize seeders and migrations on my express api and currently all the models are written in typescript using sequelize-typescript

I tried adding my first seeder file using typescript and I get an error when running it

20221028050116-feeds.ts seeder file

'use strict';

import { QueryInterface } from 'sequelize';

const feedTypes = [
  { id: 'b871a455-fddb-414c-ac02-2cdee07fa671', name: 'crypto' },
  { id: '68b15f90-19ca-4971-a2c6-67e66dc88f77', name: 'general' },
];
const feeds = [
  {
    id: 1,
    name: 'cointelegraph',
    url: 'https://cointelegraph.com/rss',
    feed_type_id: 'b871a455-fddb-414c-ac02-2cdee07fa671',
  },
];

module.exports = {
  up: (queryInterface: QueryInterface): Promise<number | object> =>
    queryInterface.sequelize.transaction(async (transaction) => {
      // here go all migration changes
      return Promise.all([
        queryInterface.bulkInsert('feed_types', feedTypes, { transaction }),
        queryInterface.bulkInsert('feeds', feeds, { transaction }),
      ]);
    }),

  down: (queryInterface: QueryInterface): Promise<object | object> =>
    queryInterface.sequelize.transaction(async (transaction) => {
      // here go all migration undo changes
      return Promise.all([
        queryInterface.bulkDelete('feed_types', null, { transaction }),
        queryInterface.bulkDelete('feeds', null, { transaction }),
      ]);
    }),
};

I added 2 commands in my package.json file to seed

"apply-seeders": "sequelize-cli db:seed:all",
"revert-seeders": "sequelize-cli db:seed:undo:all",

When I execute 'npm run apply-seeders', it gives me the following error

Sequelize CLI [Node: 16.17.0, CLI: 6.5.1, ORM: 6.23.2]


ERROR: Cannot find "/Users/vr/Desktop/code/ch/api/src/config/index.js". Have you run "sequelize init"?

ERROR: Cannot read properties of undefined (reading 'detail')
sequelize-cli db:seed:all

Run every seeder

Options:
  --version          Show version number                                                                                                                                                                  [boolean]
  --help             Show help                                                                                                                                                                            [boolean]
  --env              The environment to run the command in                                                                                                                        [string] [default: "development"]
  --config           The path to the config file                                                                                                                                                           [string]
  --options-path     The path to a JSON file with additional options                                                                                                                                       [string]
  --migrations-path  The path to the migrations folder                                                                                                                             [string] [default: "migrations"]
  --seeders-path     The path to the seeders folder                                                                                                                                   [string] [default: "seeders"]
  --models-path      The path to the models folder                                                                                                                                     [string] [default: "models"]
  --url              The database connection string to use. Alternative to using --config files                                                                                                            [string]
  --debug            When available show various debug information                                                                                                                       [boolean] [default: false]

TypeError: Cannot read properties of undefined (reading 'detail')
    at Object.error (/Users/vr/Desktop/code/ch/api/node_modules/sequelize-cli/lib/helpers/view-helper.js:43:24)
    at /Users/vr/Desktop/code/ch/api/node_modules/sequelize-cli/lib/commands/seed.js:48:39
    at async Object.exports.handler (/Users/vr/Desktop/code/ch/api/node_modules/sequelize-cli/lib/commands/seed.js:24:7)
vr@vivz api % 

I did some digging into it and it turns out that you cannot directly run typescript files with sequelize as per THIS ANSWER here

I modified my .sequelizerc file to run stuff from dist folder instead of src

.sequelizerc file

require("@babel/register");

const path = require('path');

module.exports = {
  config: path.resolve('dist', 'config', 'index.js'),
  'migrations-path': path.resolve('dist', 'data', 'migrations'),
  'models-path':     path.resolve('dist', 'data', 'models'),
  'seeders-path':    path.resolve('dist', 'data', 'seeders'),
};

Running this now gives me a different type of error

Sequelize CLI [Node: 16.17.0, CLI: 6.5.1, ORM: 6.23.2]


ERROR: Error reading "dist/config/index.js". Error: Error: Cannot find module 'babel-plugin-module-resolver'
Require stack:
- /Users/vr/Desktop/code/ch/api/node_modules/@babel/core/lib/config/files/plugins.js
- /Users/vr/Desktop/code/ch/api/node_modules/@babel/core/lib/config/files/index.js
- /Users/vr/Desktop/code/ch/api/node_modules/@babel/core/lib/index.js
- /Users/vr/Desktop/code/ch/api/node_modules/@babel/register/lib/worker/babel-core.js
- /Users/vr/Desktop/code/ch/api/node_modules/@babel/register/lib/worker/handle-message.js
- /Users/vr/Desktop/code/ch/api/node_modules/@babel/register/lib/worker-client.js
- /Users/vr/Desktop/code/ch/api/node_modules/@babel/register/lib/node.js
- /Users/vr/Desktop/code/ch/api/node_modules/@babel/register/lib/nodeWrapper.js
- /Users/vr/Desktop/code/ch/api/node_modules/@babel/register/lib/index.js
- /Users/vr/Desktop/code/ch/api/.sequelizerc
- /Users/vr/Desktop/code/ch/api/node_modules/sequelize-cli/lib/core/yargs.js
- /Users/vr/Desktop/code/ch/api/node_modules/sequelize-cli/lib/sequelize

ERROR: Cannot read properties of undefined (reading 'detail')
sequelize-cli db:seed:all

Run every seeder

Options:
  --version          Show version number                                                                                                                                                                  [boolean]
  --help             Show help                                                                                                                                                                            [boolean]
  --env              The environment to run the command in                                                                                                                        [string] [default: "development"]
  --config           The path to the config file                                                                                                                                                           [string]
  --options-path     The path to a JSON file with additional options                                                                                                                                       [string]
  --migrations-path  The path to the migrations folder                                                                                                                             [string] [default: "migrations"]
  --seeders-path     The path to the seeders folder                                                                                                                                   [string] [default: "seeders"]
  --models-path      The path to the models folder                                                                                                                                     [string] [default: "models"]
  --url              The database connection string to use. Alternative to using --config files                                                                                                            [string]
  --debug            When available show various debug information                                                                                                                       [boolean] [default: false]

TypeError: Cannot read properties of undefined (reading 'detail')
    at Object.error (/Users/vr/Desktop/code/ch/api/node_modules/sequelize-cli/lib/helpers/view-helper.js:43:24)
    at /Users/vr/Desktop/code/ch/api/node_modules/sequelize-cli/lib/commands/seed.js:48:39
    at async Object.exports.handler (/Users/vr/Desktop/code/ch/api/node_modules/sequelize-cli/lib/commands/seed.js:24:7)

This would be my tsconfig.json file

{
  "compilerOptions": {
    "lib": ["es2020"],
    "module": "commonjs",
    "moduleResolution": "node",
    "target": "es2020",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "noImplicitAny": false,
    "outDir": "dist",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "baseUrl": ".",
    "paths": {
      "server/*": ["src/server/*"],
      "tests/*": ["src/tests/*"],
      "data/*": ["src/data/*"],
      "config": ["src/config"],
    }
  }
}

Can someone kindly tell me how I can run my seeder and migration files using typescript

UPDATE 1

I installed the babel-plugin-module-resolver. Now it gives me a new error. This error doesnt show up if you run the ts files normally. When I console.log I can see all the values but when the program is run, that dialect simply doesnt load it seems from the env file

Loaded configuration file "dist/config/index.js".

ERROR: Dialect needs to be explicitly supplied as of v4.0.0

ERROR: Cannot read properties of undefined (reading 'detail')

UPDATE 2

I hardcoded the dialect postgres into the config file and it still gives me the error. I even verified that the transpiled js file has the postgres dialect specified

Neldanelia answered 28/10, 2022 at 5:49 Comment(3)
did you solved it ?Hemorrhage
@Hemorrhage yes I did, it worked at a rough glance in a separate demo I created just for this but I am yet to integrate it into the main application. I will update the answer as soon as I get it running on the main oneNeldanelia
@Hemorrhage updated my answer, hopefully that fixes the problem on your sideNeldanelia
N
5

I managed to get things to work

Your .sequelizerc and config/index.ts absolutely cannot have import export it seems

Here is my /.sequelizerc

require("@babel/register");

const path = require('path');

module.exports = {
  config: path.resolve('dist', 'config', 'index.js'),
  'migrations-path': path.resolve('dist', 'data', 'migrations'),
  'models-path':     path.resolve('dist', 'data', 'models'),
  'seeders-path':    path.resolve('dist', 'data', 'seeders'),
};

Here is my /src/config/index.ts

const config: any = {
  // if we are running tests we use an in memory db with sqlite
  dialect: process.env.DB_DIALECT,

  username: process.env.POSTGRES_USER,
  password: process.env.POSTGRES_PASSWORD,
  database: process.env.POSTGRES_DB,
  host: process.env.POSTGRES_HOST,
  port: Number(process.env.POSTGRES_PORT),
  define: {
    underscored: true,
  },
  logging: false,
};

module.exports = config;

And I am including a single seeder here

Here is my /src/data/seeders/20221116042655-feeds.ts

import { QueryInterface } from 'sequelize';
import { feedTypes, feeds } from './fixtures';

const down = (queryInterface: QueryInterface): Promise<object | object> =>
  queryInterface.sequelize.transaction(async (transaction) => {
    // here go all migration undo changes
    return Promise.all([
      queryInterface.bulkDelete('feed_types', null, { transaction }),
      queryInterface.bulkDelete('feeds', null, { transaction }),
    ]);
  });

const up = (queryInterface: QueryInterface): Promise<number | object> =>
  queryInterface.sequelize.transaction(async (transaction) => {
    // here go all migration changes
    return Promise.all([
      queryInterface.bulkInsert('feed_types', feedTypes, {
        transaction,
        // @ts-ignore
        ignoreDuplicates: true,
      }),
      queryInterface.bulkInsert('feeds', feeds, {
        transaction,
        // @ts-ignore
        ignoreDuplicates: true,
      }),
      queryInterface.sequelize.query(
        `SELECT setval('feeds_id_seq', (SELECT MAX(id) FROM feeds))`,
        { transaction },
      ),
    ]);
  });

export { down, up };

The order of operations is very important here

  1. Create required seeders

     npx sequelize-cli seed:generate --name feeds
     npx sequelize-cli seed:generate --name tag_rules
     npx sequelize-cli seed:generate --name users
    
  2. Change the extension of each of the generated js files to ts

  3. Modify .sequelizerc to read transpiled js files from dist

  4. Install babel-plugin-module-resolver

     npm i --save-dev babel-plugin-module-resolver
    

All the seeder files are using import/export and the only files using require and module.exports are .sequelizerc and config file

If anyone knows how to get these to work with the import/export syntax, feel free to suggest.

This is what my seed command inside package.json looks like

"apply-seeders": "node -r dotenv-flow/config ./node_modules/.bin/sequelize db:seed:all",
"revert-seeders": "node -r dotenv-flow/config ./node_modules/.bin/sequelize db:seed:undo:all",
Neldanelia answered 16/11, 2022 at 10:8 Comment(0)
L
1

I had the same issue when running sequelize command, which was installed globally. It was a strange issue because on other projects they were fine (not TypeScript projects).

This time I tried installing sequelize locally and run them with "npx". And it's working great again. For example:

npm install --save-dev sequelize
npx sequelize db:migrate
npx sequelize db:migrate:status

My setup was node 18.10, sequelize 6.25.5, pg 8.8.0.

Leclair answered 14/11, 2022 at 20:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.