如何使用 Knex.js 查询多对多关系?

Posted

技术标签:

【中文标题】如何使用 Knex.js 查询多对多关系?【英文标题】:How to query many to many relations with Knex.js? 【发布时间】:2020-04-08 03:25:23 【问题描述】:

我在 Postgres 中有这么多的关系:

// migrations/2020_create_initial_tables.js

exports.up = function(knex) 
  return knex.schema
    .createTable('students', function(table) 
      table.increments('id').primary()
      table
        .string('email')
        .unique()
        .index()
      table.string('password')
    )
    .createTable('courses', function(table) 
      table.increments('id').primary()
      table.string('title').notNullable()
      table.text('description')
    )
    // A student can enroll many courses
    // A course can have many students
    .createTable('student_courses', function(table) 
      table.increments('id').primary()
      table
        .integer('student_id')
        .references('id')
        .inTable('students')
      table
        .integer('course_id')
        .references('id')
        .inTable('courses')
    )
    .catch(err => 
      console.error(err)
      throw err
    )
  // .finally(() => knex.destroy());


exports.down = function(knex) 
  return knex.schema
    .dropTableIfExists('students')
    .dropTableIfExists('courses')
    .dropTableIfExists('student_courses')
    .catch(err => 
      console.error(err)
      throw err
    )

我需要显示学生注册的课程。 如何通过student.id查询(全部/数组)courses

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

堆栈:TypeScript、knex@v0.20.12、Postgres@12-alpine、pg@v7.18.2

【问题讨论】:

【参考方案1】:
const coursesOfSingleStudent = await knex('courses').whereIn('id',
   knex('student_courses').select('course_id').where('student_id', studentId)
)

虽然您最好使用 objection.js,它允许您声明关系映射,然后直接查询:

const studentWithCourses = await Student.query().findById(studentId).withGraphFetched('courses');

【讨论】:

好建议,但实际上没有关于如何的文档,例如为 m 对 m 关系创建适当的迁移。一般来说,knex & objection 的文档不是很好,委婉地说。您是否有一个很好的例子来说明如何通过迁移创建适当的 m-to-m 关系,然后将其用于反对,或者基于反对模型生成迁移? 与使用 SQL 进行迁移的方式相同...如果您的意思是如何创建表和外键等,您需要添加一个单独的问题(或者只是从 SO 中搜索答案)。无法根据数据库模型生成迁移。与 JS 世界的标准相比,Objection 实际上有相当不错的文档...... knex 没那么多。

以上是关于如何使用 Knex.js 查询多对多关系?的主要内容,如果未能解决你的问题,请参考以下文章

如何查询firebase的多对多关系?

Spring,JPA:如何使用多对多关系桥表设置查询另一个实体下的实体

SqlAlchemy 和 Flask,如何查询多对多关系

使用 Hibernate Criteria 查询多对多关系

如何查询多对多关系sequelize?

如何在 EF Core 中查询多对多关系