Sequelize-CLI Seeders - Cannot read property of undefined
Asked Answered
M

3

7

I have been struggling with the db:seed:all for over an hour now and slowly I am losing my mind about this.

I have a simple model:

'use strict';
module.exports = function (sequelize, DataTypes) {
  var Car = sequelize.define('Cars', {
    name: DataTypes.STRING,
    type: DataTypes.INTEGER,
    models: DataTypes.INTEGER
  }, {
      classMethods: {
        associate: function (models) {
          // associations can be defined here
        }
      }
    });
  return Car;
};

this is in a migration and goes to the database using sequelize db:migrate which works fine.

Next I wanted to insert - through a seed file - 2 cars. So I ran the command sequelize seed:create --name insertCars and added the bulkInsert:

'use strict';

module.exports = {
  up: function (queryInterface, Sequelize) {
    return queryInterface.bulkInsert(
      'Cars',
      [
        {
          name: "Auris",
          type: 1,
          models: 500,
          createdAt: Date.now(), updatedAt: Date.now()
        },
        {
          name: "Yaris",
          type: 1,
          models: 500,
          createdAt: Date.now(), updatedAt: Date.now()
        }
      ]
    );
  },

  down: function (queryInterface, Sequelize) {
  }
};

Now when I run sequelize db:seed:all I get following error:

Loaded configuration file "config\config.json".
Using environment "development".
== 20160510132128-insertCars: migrating =======
Seed file failed with error: Cannot read property 'name' of undefined

Has anyone got any experience with running these seeders? For your information here is my config file:

{
  "development": {
    "username": "mydbdude",
    "password": "mydbdude",
    "database": "Cars",
    "host": "127.0.0.1",
    "dialect": "mssql",
    "development": {
      "autoMigrateOldSchema": true
    }
  },
  ....other configs
}

EDIT: Output from db:migrate

Sequelize [Node: 5.9.1, CLI: 2.4.0, ORM: 3.23.0]

Loaded configuration file "config\config.json".
Using environment "development".
No migrations were executed, database schema was already up to date.
Muco answered 10/5, 2016 at 14:12 Comment(4)
Hi, can you show the terminal output of sequelize db:migrate?Effieeffigy
@Effieeffigy I editted my original question and added the output from db:migrate at the bottomMuco
what DB dialect are you using? I've had issues with Postgres and case sensitive names (ie. Cars vs. the cars table postgres creates)Vasques
Mssql, normally that should nog be case sensitive right? and even if, I have my model and table cased the same CarsMuco
M
3

Since I still have not been able to get this working, I, now then, post my solution I used which works rather well but is custom built.

First, I have created a JSON file containing the object I want to seed. i.e.

dataSources: [
    {
        name: 'Pattern'
    },
    {
        name: 'Upload'
    }
]

Next, I have implemented a seeder.js in the server side of my application containing the following (trimmed version of course)

var models = require('./../models'),
sql = models.sequelize,
Promise = models.Sequelize.Promise;

var objects = require('./seed/objects'), //this is where my object file is
dataSources = objects.dataSources;


var express = require('express');

var seedDatabase = function () {
    var promises = [];
    promises.push(createDataSources());
    //more can be added to the promises

    return Promise.all(promises);
};

function createDataSources() {
    return models.sequelize
        .transaction(
            {
                isolationLevel: models.sequelize.Transaction.ISOLATION_LEVELS.READ_COMMITTED
            },
            function (t) {
                return models.DataSource
                    .findAll({
                        attributes: [
                            'id'
                        ]
                    })
                    .then(function (result) {
                        if (!result || result.length == 0) {
                            return models.DataSource
                                .bulkCreate(dataSources, { transaction: t })
                                .then(function () {
                                    console.log("DataSources created");
                                })
                        }
                        else {
                            console.log("DataSources seeder skipped, already objects in the database...");
                            return;
                        }
                    });
            })
        .then(function (result) {
            console.log("DataSources seeder finished...");
            return;
        })
        .catch(function (error) {
            console.log("DataSources seeder exited with error: " + error.message);
            return;
        });
};

module.exports = {
    seedDatabase: seedDatabase
}

Now all this setup is done, I can use this seedDatabase function when my application starts in order to run my seeder, like so:

//includes and routes above, not interesting for this answer
try {
    umzug.up().then(function (migrations) {
        for (var i = 0; i < migrations.length; i++) {
            console.log("Migration executed: " + migrations[i].file);
        }

        console.log("Running seeder");
        seeder.seedDatabase().then(function () { //here I run my seeders
            app.listen(app.get('port'), function () {
                console.log('Express server listening on port ' + app.get('port'));
            });
        });
    });
}
catch (e) {
    console.error(e);
}

That's it, now, when you run your application, the seeder will check the database if any of your objects are already inserted in the database. If so, the seeder is skipped, if not, they are inserted.

I hope this will help you guys.

Muco answered 21/9, 2016 at 6:41 Comment(0)
B
1

I had same issue the problem was that I added extra commas in between objects check for any syntax error that might work

 dataSources: [
    {
        name: 'Pattern'
    },
    ,// this comma was added by mistake for me
    {
        name: 'Upload'
    }
 ]
Barbel answered 23/11, 2020 at 8:52 Comment(0)
A
0

I ended up here because I included updateOnDuplicate in the options during my bulkInsert. It seems this option is intended to be paired with another field known as 'upsertKeys'. These two properties should be arrays representing the columns of the table where you're performing a bulk insert eg:

queryInterface.bulkInsert(
  "table_name",
  mapDataAndAddCreatedAndUpdatedAtField(array_of_db_entries),
  {
    transaction,
    ignoreDuplicates: false,
    updateOnDuplicate: ["col1", "col2", ..., "coln"],
    upsertKeys: ["unique_col1", ..., "unique_coln"],
  }
);
Afb answered 26/7, 2023 at 7:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.