Node.js Sequelize多对多关系在使用GET请求时不显示关系

Node.js Sequelize多对多关系在使用GET请求时不显示关系,node.js,express,sequelize.js,many-to-many,Node.js,Express,Sequelize.js,Many To Many,我是关系数据库的新手。我使用NodeJS和express作为后端,RESTAPI和数据库是Postgresql。我使用Sequelize连接和模型。我创建了两个模型,一个是学生模型,另一个是课程模型。我的目标是一个学生可以有多个课程,也要防止重复的学生姓名,电话,电子邮件。我成功连接到数据库并能够发布请求。当然,我是这样发的。从测试的应用程序,我使用邮递员。但当我试图得到学生或课程的要求时我看不出学生与课程之间有任何关系。这里是可视化和可视化。 这是 这是我的学生模型 const Student

我是关系数据库的新手。我使用NodeJS和express作为后端,RESTAPI和数据库是Postgresql。我使用Sequelize连接和模型。我创建了两个模型,一个是学生模型,另一个是课程模型。我的目标是一个学生可以有多个课程,也要防止重复的学生姓名,电话,电子邮件。我成功连接到数据库并能够发布请求。当然,我是这样发的。从测试的应用程序,我使用邮递员。但当我试图得到学生或课程的要求时我看不出学生与课程之间有任何关系。这里是可视化和可视化。 这是

这是我的学生模型

const Student = con.define("student", {
      id: {
        type: sequelize.INTEGER,
        primaryKey: true
      },
      name: {
        type: sequelize.STRING,
        allowNull: false
      },
      birthday: {
        type: sequelize.DATEONLY,
        allowNull: false
      },
      address: {
        type: sequelize.STRING,
        allowNull: false
      },
      zipcode: {
        type: sequelize.INTEGER,
        allowNull: false
      },
      city: {
        type: sequelize.STRING,
        allowNull: false
      },
      phone: {
        type: sequelize.BIGINT,
        allowNull: false
      },

      email: {
        type: sequelize.STRING,
        allowNull: false,
        validate: {
          isEmail: true
        }
      }
    });
const Course = con.define("course", {
  name: { type: sequelize.STRING },
  startdate: { type: sequelize.DATEONLY },
  enddate: { type: sequelize.DATEONLY },
  studentId: { type: sequelize.INTEGER, foreignKey: true }
});
这是课程模式

const Student = con.define("student", {
      id: {
        type: sequelize.INTEGER,
        primaryKey: true
      },
      name: {
        type: sequelize.STRING,
        allowNull: false
      },
      birthday: {
        type: sequelize.DATEONLY,
        allowNull: false
      },
      address: {
        type: sequelize.STRING,
        allowNull: false
      },
      zipcode: {
        type: sequelize.INTEGER,
        allowNull: false
      },
      city: {
        type: sequelize.STRING,
        allowNull: false
      },
      phone: {
        type: sequelize.BIGINT,
        allowNull: false
      },

      email: {
        type: sequelize.STRING,
        allowNull: false,
        validate: {
          isEmail: true
        }
      }
    });
const Course = con.define("course", {
  name: { type: sequelize.STRING },
  startdate: { type: sequelize.DATEONLY },
  enddate: { type: sequelize.DATEONLY },
  studentId: { type: sequelize.INTEGER, foreignKey: true }
});
这是我的多对多关系设置

const StudentCourse = con.define("studentCourses", {
  id: {
    type: sequelize.INTEGER,
    primaryKey: true
  },
  courseId: { type: sequelize.INTEGER, foreignKey: true },
  studentId: { type: sequelize.INTEGER, foreignKey: true }
});

Student.belongsToMany(Course, { through: StudentCourse, as: "courses" });
Course.belongsToMany(Student, { through: StudentCourse, as: "students" });

//con.sync({ force: true });

module.exports = { Student, Course, StudentCourse };
这是我的REST API设置。学生和课程帖子请求

//Student post request
    app.post("/students", async (req, res, next) => {
      try {
        const logs = new Student(req.body);
        const entry = await logs.save();
        res.json(entry);
      } catch (error) {
        if (error.name === "ValidationError") {
          res.status(422);
        }
        next(error);
      }
    });


//Course post request 

    app.post("/courses", async (req, res, next) => {
      try {
        const logs = new Course(req.body);
        const entry = await logs.save();
        res.json(entry);
      } catch (error) {
        if (error.name === "ValidationError") {
          res.status(422);
        }
        next(error);
      }
    });
*这是学生端和课程端的GET请求设置,我看不到结果

app.get("/student", async (req, res, next) => {
  try {
    await Student.findAll({
      include: {
        model: Course,
        through: StudentCourse,
        as: "courses"
      }
    }).then(docs => {
      res.json(docs);
    });
  } catch (error) {
    console.log(error);
  }
});

app.get("/course", async (req, res, next) => {
  try {
    await Course.findAll({
      include: {
        model: Student,
        through: StudentCourse,
        as: "students"
      }
    }).then(docs => {
      res.json(docs);
    });
  } catch (error) {
    console.log(error);
  }
});

看来你犯了一些基本的错误。如果关系是多对多,则课程模型不应包含任何外键(studentId),因为一门课程可以有多个学生。如果这门课程有1、2和3名学生,学生会是什么?没有意义(除非您使用NOSQL,否则您可以使用一个id数组作为引用)

这就是“连接表”出现的地方,它的唯一目的是存储课程和学生之间的关系。从课程中删除studentId列

另外,我会在promary键上加上autoIncrement:true,因为如果没有它,您将需要手动创建ID,这是非常错误的。关于电子邮件,它需要具有唯一性:true

我还必须将所有类型从sequelize[type]更改为DataTypes[type]。你没有收到任何错误吗

我测试了您的代码(当然没有错误的列),只做了一些轻微的修改,GET路由似乎可以工作(我没有测试POST,只是将记录手动插入数据库)。你确定你有记录吗

在课程模型中不使用不必要的外键进行尝试。确保数据库中有记录(因为问题可能是POST,而不是GET)。如果不起作用,请提供更多详细信息和代码

添加了一张图片,显示GET适用于我:

编辑:sequelize的文档在我看来非常糟糕,老实说,我不再使用这个ORM了。但我就是这样发布了一个有关系的学生:

app.post("/students", async (req, res, next) => {
    try {

      const student = await Student.create(req.body)
      const course = await Course.findOne({where:{id:1}})//Get the course you want to "add" to the user, by id.
      //Notice that here the id hard-coded. You will need to supply it from where-ever..
      await student.addCourse(course)
      res.json(student);
    } catch (error) {
      if (error.name === "ValidationError") {
        res.status(422);
      }
      next(error);
    }
  });
此路线创建一个学生,并将其与ID为1的课程相关联(假设该课程当然存在)

请注意,这实际上非常糟糕:它执行一个不必要的查询来根据课程ID获取课程,只是为了能够使用student.addCourse函数。我认为使用Sequelize有更好的方法,您需要在文档和教程中探索。我个人永远不会这样做,我只会对连接表执行一个原始查询,将关系添加到一个单独的路由,我可能会称之为“addStudentCourse”,它依赖于通过AJAX提供的用户ID和courseId。如果你想知道怎么做,让我知道


再次:我发现sequelize文档写得很糟糕,最好不要使用这个ORM。此外,学习SQL对一个人的职业生涯非常有益。记住这一点:D

所以这里似乎有一些基本的错误。如果关系是多对多,则课程模型不应包含任何外键(studentId),因为一门课程可以有多个学生。如果这门课程有1、2和3名学生,学生会是什么?没有意义(除非您使用NOSQL,否则您可以使用一个id数组作为引用)

这就是“连接表”出现的地方,它的唯一目的是存储课程和学生之间的关系。从课程中删除studentId列

另外,我会在promary键上加上autoIncrement:true,因为如果没有它,您将需要手动创建ID,这是非常错误的。关于电子邮件,它需要具有唯一性:true

我还必须将所有类型从sequelize[type]更改为DataTypes[type]。你没有收到任何错误吗

我测试了您的代码(当然没有错误的列),只做了一些轻微的修改,GET路由似乎可以工作(我没有测试POST,只是将记录手动插入数据库)。你确定你有记录吗

在课程模型中不使用不必要的外键进行尝试。确保数据库中有记录(因为问题可能是POST,而不是GET)。如果不起作用,请提供更多详细信息和代码

添加了一张图片,显示GET适用于我:

编辑:sequelize的文档在我看来非常糟糕,老实说,我不再使用这个ORM了。但我就是这样发布了一个有关系的学生:

app.post("/students", async (req, res, next) => {
    try {

      const student = await Student.create(req.body)
      const course = await Course.findOne({where:{id:1}})//Get the course you want to "add" to the user, by id.
      //Notice that here the id hard-coded. You will need to supply it from where-ever..
      await student.addCourse(course)
      res.json(student);
    } catch (error) {
      if (error.name === "ValidationError") {
        res.status(422);
      }
      next(error);
    }
  });
此路线创建一个学生,并将其与ID为1的课程相关联(假设该课程当然存在)

请注意,这实际上非常糟糕:它执行一个不必要的查询来根据课程ID获取课程,只是为了能够使用student.addCourse函数。我认为使用Sequelize有更好的方法,您需要在文档和教程中探索。我个人永远不会这样做,我只会对连接表执行一个原始查询,将关系添加到一个单独的路由,我可能会称之为“addStudentCourse”,它依赖于通过AJAX提供的用户ID和courseId。如果你想知道怎么做,让我知道


再次:我发现sequelize文档写得很糟糕,最好不要使用这个ORM。此外,学习SQL对一个人的职业生涯非常有益。记住这一点:D

嗨,非常感谢你这么好的作品