Sequelize通过关联创建

时间:2017-03-01 16:36:59

标签: node.js associations sequelize.js

我正在为两个类之间的关联开发一个create方法。 sequelize文档表明这可以使用包含

一步完成
IntramuralAthlete.create(intramuralAthlete,{
         include: [Person]
    }).then((data,err)=>{
         if(data)res.json(data);
         else res.status(422).json(err);
    }).catch(function(error) {
         res.status(422).json({message: "failed to create athlete", error: error.message});
});

我的模型关联看起来像这样

var Person = require('../models').person;
var IntramuralAthlete = require('../models').intramuralAthlete;

IntramuralAthlete.belongsTo(Person);

当我登录时,校内运动员的价值是

{ 
   person: 
   { firstName: 'Test',
     lastName: 'User',
     email: 'test@user.com'
  },
  grade: '12th',
  organizationId: 1 
}

但我收到错误notNull Violation: personId cannot be null。这个错误让我听起来像Sequelize表示我打算在同一个调用中创建personId的方式听起来有些不对劲。

我向create语句指示使用IntramuralAthlete创建的相关表格的方式是否有问题?

谢谢!

编辑: 我也尝试使用以下结构,结果相同

{ 
  Person: { 
    firstName: 'Test',
    lastName: 'User',
    email: 'test@user.com'
 },
 grade: '12th',
 organizationId: 1 
}

我的模型如下:

module.exports = function(sequelize, DataTypes) {
  return sequelize.define('intramuralAthlete', {
    id: {
      type: DataTypes.INTEGER(11),
      allowNull: false,
      primaryKey: true,
      autoIncrement: true
    },
    createdAt: {
      type: DataTypes.DATE,
      allowNull: false,
      defaultValue: sequelize.literal('CURRENT_TIMESTAMP')
    },
    updatedAt: {
      type: DataTypes.DATE,
      allowNull: false,
      defaultValue: sequelize.literal('CURRENT_TIMESTAMP')
    },
    grade: {
      type: DataTypes.STRING,
      allowNull: true
    },
    age: {
      type: DataTypes.INTEGER(11),
      allowNull: true
    },
    school: {
      type: DataTypes.STRING,
      allowNull: true
    },
    notes: {
      type: DataTypes.STRING,
      allowNull: true
    },
    guardianId: {
      type: DataTypes.INTEGER(11),
      allowNull: true,
      references: {
        model: 'contact',
        key: 'id'
      }
    },
    personId: {
      type: DataTypes.INTEGER(11),
      allowNull: false,
      references: {
        model: 'person',
        key: 'id'
      }
    },
    mobileAthleteId: {
      type: DataTypes.INTEGER(11),
      allowNull: true,
      references: {
        model: 'mobileAthlete',
        key: 'id'
      }
    },
    organizationId: {
      type: DataTypes.INTEGER(11),
      allowNull: false,
      references: {
        model: 'organization',
        key: 'id'
      }
    }
  }, {
    tableName: 'intramuralAthlete'
  });
};

2 个答案:

答案 0 :(得分:5)

我认为您的模型名为PersonIntramuralAthletesequelize.define方法的第一个参数)。在这种情况下,当您创建与您的关联类似且未定义as属性时,您的create数据对象应如下所示

{
    Person: {
        firstName: 'Test',
        lastName: 'User',
        email: 'test@user.com'
    },
    grade: '12th',
    organizationId: 1 
}

如果您想使用person(就像在代码中一样),您应该稍微区别地定义关联

IntramuralAthlete.belongsTo(Person, { as: 'person' });

然后,您必须在create的{​​{1}}属性中对此include查询执行某些更改

options

编辑:使用空值IntramuralAthlete.create(data, { include: [ { model: Person, as: 'person' } ] }).then((result) => { // both instances should be created now });

欺骗save()方法

如果您执行此类操作,则可以维护personId

allowNull: false

编辑2 :创建时禁用验证。

此案例假定验证已关闭。省略模型验证似乎是一个坏主意,但是仍然维护数据库表级验证 - 在迁移中定义,它仍然可以检查是否设置了{ person: { // person data }, personId: '', // whatever value - empty string, empty object etc. grade: '12th', organizationId: 1 }

personId

在这种情况下,IntramuralAthlete.create(data, { include: [ { model: Person, as: 'person' } ], validate: false }).then((result) => { // both instances should be created now }); 对象可以与您的示例中一样 - 没有data属性。我们省略了允许传递personId值的模型级验证,但是如果在null方法期间它仍然是save()值,则数据库级验证会引发错误。

答案 1 :(得分:0)

首先,当您将模型与 belongsTo 相关联时,sequelize会自动将目标模型主键添加为源模型中的外键。在大多数情况下,您不需要自己定义它,因此在您定义IntramuralAthlete.belongsTo(Person) sequelize时PersonIdIntramuralAthlete添加为IntramuralAthlete中的外键。您的module.exports = function(sequelize, DataTypes) { return sequelize.define('intramuralAthlete', { grade: { type: DataTypes.STRING, allowNull: true }, age: { type: DataTypes.INTEGER(11), allowNull: true }, school: { type: DataTypes.STRING, allowNull: true }, notes: { type: DataTypes.STRING, allowNull: true } }); }; 模型应如下所示:

intramuralAthlete

现在您可以像上面的代码一样创建 let data = { Person: { firstName: 'Test', lastName: 'User', email: 'test@user.com' }, grade: '12th', notes: 'test notes' } IntramuralAthlete.create(data, {include: [Person]}).then((result) => { // both instances should be created now }); 。例如:

IntramuralAthlete

小心模型名称。 第二,我认为您的belongsTo模型有多个IntramuralAthlete关联。只需将它们定义为前一个关联,sequelize将其主键作为外键添加到id模型中。

第三,当您定义模型时,sequelize会自动添加createdAt数据字段作为主键和自动增量,并添加updatedAtCURRENT_TIMESTAMP个数据字段,默认为router/index.js值,因此您无需在模型中定义它们