首页 文章

Sequelize通过关联创建

提问于
浏览
3

我正在为两个类之间的关联开发一个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);

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

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

但我收到错误 notNull Violation: personId cannot be null . 这个错误让我觉得我打算在同一个调用中创建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 回答

  • 5

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

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

    如果你想使用 person (就像你的代码一样),你应该稍微改变一下联想的定义

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

    然后,你必须在 optionsinclude 属性中的 create 查询中执行一些更改,就像这样

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

    EDIT :使用空值 personId 欺骗 save() 方法

    如果你这样做,你可以维护 allowNull: false

    {
        person: {
            // person data
        },
        personId: '', // whatever value - empty string, empty object etc.
        grade: '12th',
        organizationId: 1
    }
    

    EDIT 2 :创建时禁用验证 .

    此案例假定验证已关闭 . 省略模型验证似乎是一个坏主意,但是仍然维护数据库表级验证 - 在迁移中定义,它仍然可以检查是否设置了 personId

    IntramuralAthlete.create(data, {
        include: [
            { model: Person, as: 'person' }
        ],
        validate: false
    }).then((result) => {
        // both instances should be created now
    });
    

    在这种情况下, data 对象可以与您的示例中一样 - 没有 personId 属性 . 我们省略了允许传递 null 值的模型级验证,但是如果在 save() 方法期间它仍然是 null 值 - 数据库级验证会抛出错误 .

  • 0

    首先,当您将模型与 belongsTo 关联时,sequelize将自动将目标模型主键添加为源模型中的外键 . 在大多数情况下,您不需要自己定义它,因此在您定义 IntramuralAthlete.belongsTo(Person) 时,sequelize会在 IntramuralAthlete 中添加 PersonId 作为外键 . 你的 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 关联 . 只需将它们定义为前一个关联,sequelize将其主键作为外键添加到 IntramuralAthlete 模型中 .

    第三,当你定义一个模型时,sequelize会自动添加一个 id 数据字段作为主键和自动增量,并且还会添加 createdAtupdatedAt 数据字段以及默认的 CURRENT_TIMESTAMP 值,因此您无需在模型中定义它们

相关问题