Cli: question: createdAt & updatedAt default value

Created on 14 Jan 2017  路  14Comments  路  Source: sequelize/cli

Why doesn't sequelize model:create foobar --attributes 'foo:string, bar:string add the default value now() to createdAt and updatedAt?

'use strict';
module.exports = {
  up: function(queryInterface, Sequelize) {
    return queryInterface.createTable('foobar', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      foo: {
        type: Sequelize.STRING
      },
      bar: {
        type: Sequelize.STRING
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
  },
  down: function(queryInterface, Sequelize) {
    return queryInterface.dropTable('foobar');
  }
};

Most helpful comment

you can add
createdAt: new Date(), updatedAt: new Date() to all the seeds, but maybe it should be documented somewhere?

All 14 comments

Check enabling 'timestamps:true' in your options. And why isn't your tables modular?

Create your tables like so:
``` 'use strict';

module.exports = (sequelize, Sequelize) => {
const projects = sequelize.define('projects',
{
id: {
type: Sequelize.UUID,
allowNull: false,
primaryKey: true,
unique: true
},
uid: {
type: Sequelize.UUID,
allowNull: false,
defaultValue: Sequelize.UUIDV4,

  },
  client: {
    type: Sequelize.STRING(255),
    allowNull: false
  },
  name: {
    type: Sequelize.STRING(255),
    allowNull: false
  },

},
{
  tableName: 'projects',
  freezeTableName: true,
  underscored: false,
  // don't forget to enable timestamps!
  timestamps: true,
  // I don't want createdAt
  createdAt: 'dateCreated',
  // I want updatedAt to actually be called updateTimestamp
  updatedAt: 'dateModified',
  // And deletedAt to be called destroyTime (remember to enable paranoid for this to work)
  deletedAt: 'dateDestroyed',
  // Paranoid will not delete tables from cascade only add delete to active

});

return projects;
};

Then do this:
'use strict';

let models = require('../Models/index');

module.exports = {
up: function (queryInterface, Sequelize) {
return Promise.resolve()
.then(() => {
return queryInterface.createTable(models.projects.tableName,
models.projects.attributes, models.projects.options);
});
},
down: function (queryInterface, Sequelize) {
return Promise.resolve()
.then(() => {
return queryInterface.dropAllTable();
});
}
};
````

The CLI generates createdAt and updatedAt for the migrations, should we then also manually change each migration to include timestamps: true? I'm confused.

edit: the createdAt and updatedAt generated by the cli do not have any default values

When the CLI generates createAt and updatedAt each of these should have a default prop for the current timestamp.

createdAt: {
        allowNull: false,
        type: Sequelize.DATE,
       default: now()
      }

I don't use sequelize anymore. So this can be closed as I appear to be the only one that wants this feature.

Adding default should not be required as Sequelize handles them and it doesnt use database default values for maintaining these fields

Adding default should not be required as Sequelize handles them and it doesnt use database default values for maintaining these fields

It shouldn't yet I still have ERROR: Field 'createdAt' doesn't have a default value

'use strict';

module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('users', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      email: {
        type: Sequelize.STRING
      },
      password: {
        type: Sequelize.STRING
      },
      name: {
        type: Sequelize.STRING
      },
      lastName: {
        type: Sequelize.STRING
      },
      address: {
        type: Sequelize.STRING
      },
      phoneNumber: {
        type: Sequelize.STRING
      },
      position: {
        type: Sequelize.STRING
      },
      department: {
        type: Sequelize.STRING
      },
      createdAt: {
        type: Sequelize.DATE
      },
      updatedAt: {
        type: Sequelize.DATE
      }
    }, {
      indexes: [{
        unique: true,
        fields: ['email']
      }]
    });
  },

  down: (queryInterface, Sequelize) => {
    queryInterface.dropTable('users');
  }
};

This fails subsequent migrations, adds table users but doesn't add new row to SequelizeMeta making it impossible to revert migration

This still fails.
In a new project:

  1. node_modules/.bin/sequelize model:generate --name User --attributes username
  2. node_modules/.bin/sequelize db:migrate
  3. node_modules/.bin/sequelize seed:generate --name new-users
  4. edit seed to insert a user using bulkInsert following the generated example
  5. node_modules/.bin/sequelize db:seed:all gives ERROR: Field 'createdAt' doesn't have a default value
  6. edit model to include timestamps:true
  7. same error

you can add
createdAt: new Date(), updatedAt: new Date() to all the seeds, but maybe it should be documented somewhere?

I agree, the documentation contradicts what actually happens. Creating First Seed fails, as @francof said.

Thanks @francof
Is was a pain to me to understand what happened with these errors !!

Thanks again

The suggestion from @francof is shown in the bulkInsert docs.

http://docs.sequelizejs.com/class/lib/query-interface.js~QueryInterface.html#instance-method-bulkInsert

queryInterface.bulkInsert('roles', [{
   label: 'user',
   createdAt: new Date(),
   updatedAt: new Date()
 }, {
   label: 'admin',
   createdAt: new Date(),
   updatedAt: new Date()
 }]);

Stumbled over the same issue, please update the docs:

http://docs.sequelizejs.com/manual/migrations.html#creating-first-seed

This example wont work the way it is displayed now due to missing timestamps.

This issue still happens. Document#Creating First Seed must be updated as follows.

'use strict';

module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.bulkInsert('Users', [{
        firstName: 'John',
        lastName: 'Doe',
        email: '[email protected]',
        createdAt: new Date(),
        updatedAt: new Date()
      }], {});
  },

  down: (queryInterface, Sequelize) => {
    return queryInterface.bulkDelete('Users', null, {});
  }
};

Add defaultValue manually after generating the migration file, this issue will not happen.

'use strict';
// 20190620055759-create-user.js
module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('Users', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      username: {
        type: Sequelize.STRING
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE,
        defaultValue: new Date()
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE,
        defaultValue: new Date()
      }
    });
  },
  down: (queryInterface, Sequelize) => {
    return queryInterface.dropTable('Users');
  }
};

@zuoyi615 Wouldn't it set a default value to a hard-coded date at the time of execution? That's not what's happening with DEFAULT now() in e.g. PostgreSQL.

Was this page helpful?
0 / 5 - 0 ratings