Javascript Sequelize保存/创建方法仅在第一次在CRUD应用程序上有效

Javascript Sequelize保存/创建方法仅在第一次在CRUD应用程序上有效,javascript,mysql,node.js,sequelize.js,es6-promise,Javascript,Mysql,Node.js,Sequelize.js,Es6 Promise,一般问题: 我一直在努力使用JavaScript+NodeJS+express+sequelize(MySQL)构建一个简单的CRUD应用程序 项目的情境化 我的CRUD应用程序正在开发中,用于管理某位英语教师的学生 创建了一些表格模型:Alunos-English:Students、Boletos-English:Pay Order、Aulas-English:Classes,以及其他目前不强制解释此问题的表格模型 具体问题: 这里有一个帖子路径,它将我的一些身体内容插入到表“Alunos”中

一般问题:
我一直在努力使用JavaScript+NodeJS+express+sequelize(MySQL)构建一个简单的CRUD应用程序

项目的情境化
我的CRUD应用程序正在开发中,用于管理某位英语教师的学生
创建了一些表格模型:Alunos-English:Students、Boletos-English:Pay Order、Aulas-English:Classes,以及其他目前不强制解释此问题的表格模型

具体问题:
这里有一个帖子路径,它将我的一些身体内容插入到表“Alunos”中。创建包含学生数据的行后,我需要为“Boletos”创建注册表,这将是12个月的付款单注册到此表中。这一部分有两个问题:第一个问题是我注册了一个学生,它可以正常工作,但我无法获取模型生成的自动增量id,以插入外键“AlunoId”,因此“Boletos”表的外键设置为null。另一个问题是,这两个条目(1到“Alunos”和12到“Boletos”)一开始运行良好,可以注册第一个学生,但在刷新页面并尝试注册另一个学生后,node JS抛出一个错误:

代码:

  • 型号-Alunos:
  • //创建Aluno表模型并导出以调用到其他文件
    module.exports=(sequelize,数据类型)=>{
    const Aluno=sequelize.define('Aluno'{
    姓名:{
    类型:DataTypes.STRING,
    allowNull:错,
    },
    姓:{
    类型:DataTypes.STRING,
    allowNull:错,
    },
    出生:{
    类型:DataTypes.DATEONLY,
    allowNull:错,
    },
    电话号码:{
    类型:DataTypes.STRING,
    阿洛诺:是的,
    独一无二:没错,
    },
    手机号码:{
    类型:DataTypes.STRING,
    allowNull:错,
    },
    电邮:{
    类型:DataTypes.STRING,
    allowNull:错,
    },
    住宅地址:{
    类型:DataTypes.STRING,
    allowNull:错,
    },
    职业:{
    类型:DataTypes.STRING,
    allowNull:错,
    },
    公司:{
    类型:DataTypes.STRING,
    allowNull:错,
    },
    每周上课人数:{
    类型:DataTypes.INTEGER,
    allowNull:错,
    },
    上课日:{
    类型:DataTypes.STRING,
    allowNull:错,
    },
    上课时间:{
    类型:DataTypes.TIME,
    allowNull:错,
    },
    开始于:{
    类型:DataTypes.DATEONLY,
    allowNull:错,
    },
    价值:{
    类型:DataTypes.FLOAT,
    allowNull:错,
    },
    折扣:{
    类型:DataTypes.FLOAT,
    默认值:0,
    },
    截止日期:{
    类型:DataTypes.DATEONLY,
    allowNull:错,
    },
    });
    Aluno.associate=(型号)=>{
    Aluno.有很多(models.Aula{
    onDelete:'级联',
    });
    };
    Aluno.associate=(型号)=>{
    Aluno.有很多(models.Boleto{
    onDelete:“无操作”,
    });
    };
    Aluno.associate=(型号)=>{
    Aluno.hasMany(型号:Assiste_Aula{
    onDelete:“无操作”,
    });
    };
    返回Aluno;
    };
    
  • 型号-Boletos:
  • 路线-邮政注册:

    // Post Routes
    router.post('/realizado', async (req, res) => {
      // Create Aluno
      // Compute values of some attributes
      var cls_day = req.body.classes_day;
      var num_cls = cls_day.length;
    
      var dias;
      for (let i = 0; i < num_cls; i++) {
        if (i + 1 < num_cls) {
          dias += cls_day[i] + '-';
        } else {
          dias += cls_day[i];
        }
      }
    
      // Instantiate Aluno model
      const aluno = db.Aluno.build({
        name: req.body.name,
        surname: req.body.surname,
        birth: req.body.birth,
        phone_number: req.body.phone_number,
        mobile_number: req.body.mobile_number,
        email: req.body.email,
        residential_address: req.body.residential_address,
        profession: req.body.profession,
        company: req.body.company,
        num_classes_week: num_cls,
        classes_day: dias,
        classes_time: req.body.classes_time,
        starts_at: req.body.starts_at,
        value: req.body.value,
        discount: req.body.discount,
        due_date: req.body.due_date,
      });
    
      // Insert into database
      const newAluno = await aluno.save();
    
      // Create boleto
      var objList = [];
      for (var i = 0; i < 12; i++) {
        var firstDt = new Date(req.body.due_date);
    
        // Compute current date
        var dt = firstDt.setMonth(firstDt.getMonth() + i);
        //dt.setDate(dt.getMonth() + i)
        // Build boleto object
        var boleto;
        boleto = db.Boleto.build({
          value: req.body.value,
          due_date: dt,
          alunoId: newAluno.id,
        });
    
        objList.push(boleto);
      }
    
      for (var i = 0; i < objList.length; i++) {
        try {
          await objList[i].save();
        } catch (err) {
          console.log(err);
        }
      }
      res.render('realizado');
    });
    
    //发布路由
    路由器.post('/realizado',异步(req,res)=>{
    //创建Aluno
    //计算某些属性的值
    var cls_day=需求主体类_day;
    var num_cls=cls_day.length;
    瓦迪亚斯;
    for(设i=0;i
    最后考虑:
    因为我是NodeJS和JavaScript新手,所以我不知道承诺和语法sugar
    await/async
    。我已经学习了很多视频,我想我已经掌握了关于它的基本概念,但是我无法将它应用到项目中。

    您需要使用
    db.Aluno.create()
    或设置
    db.Aluno.build({…},{isNewRecord:true})
    让Sequelize知道这是一个插入,而不是主键值为0的记录。您的DB可能看到ID为0,并将其插入或设置为1,无论哪种方式,您都会在第二次插入时遇到冲突

    将路由器/控制器代码封装在
    try/catch
    中处理任何错误也是一个好主意。使用传递给所有查询/插入的事务,以便在任何阶段出现错误时都可以回滚它们-const transaction=wait sequelize.transaction();const aluno=wait db.aluno.create({…},{transaction});。使用wait
    transaction.Commit()
    在末尾提交,或在catch块中使用
    wait transaction.rollback()
    回滚

    module.exports = (sequelize, DataTypes) => {
        const Boleto = sequelize.define('Boleto', {
            value: {
                type: DataTypes.FLOAT,
                allowNull: false
            },
            due_date: {
                type: DataTypes.DATEONLY,
                allowNull: false
            },
            status: {
                type: DataTypes.INTEGER,
                defaultValue: 0,
                allowNull: false
            }
        })
    
        Boleto.associate = (models) => {
            Boleto.belongsTo(models.Aluno, {
                foreignKey: 'AlunoId'  
            })
        }
    
        return Boleto
    }
    
    // Post Routes
    router.post('/realizado', async (req, res) => {
      // Create Aluno
      // Compute values of some attributes
      var cls_day = req.body.classes_day;
      var num_cls = cls_day.length;
    
      var dias;
      for (let i = 0; i < num_cls; i++) {
        if (i + 1 < num_cls) {
          dias += cls_day[i] + '-';
        } else {
          dias += cls_day[i];
        }
      }
    
      // Instantiate Aluno model
      const aluno = db.Aluno.build({
        name: req.body.name,
        surname: req.body.surname,
        birth: req.body.birth,
        phone_number: req.body.phone_number,
        mobile_number: req.body.mobile_number,
        email: req.body.email,
        residential_address: req.body.residential_address,
        profession: req.body.profession,
        company: req.body.company,
        num_classes_week: num_cls,
        classes_day: dias,
        classes_time: req.body.classes_time,
        starts_at: req.body.starts_at,
        value: req.body.value,
        discount: req.body.discount,
        due_date: req.body.due_date,
      });
    
      // Insert into database
      const newAluno = await aluno.save();
    
      // Create boleto
      var objList = [];
      for (var i = 0; i < 12; i++) {
        var firstDt = new Date(req.body.due_date);
    
        // Compute current date
        var dt = firstDt.setMonth(firstDt.getMonth() + i);
        //dt.setDate(dt.getMonth() + i)
        // Build boleto object
        var boleto;
        boleto = db.Boleto.build({
          value: req.body.value,
          due_date: dt,
          alunoId: newAluno.id,
        });
    
        objList.push(boleto);
      }
    
      for (var i = 0; i < objList.length; i++) {
        try {
          await objList[i].save();
        } catch (err) {
          console.log(err);
        }
      }
      res.render('realizado');
    });