如何从Knex QueryBuilder中找回已添加的关联查询?
给Knex查询的主表及关联表统一添加Schema
Knex的QueryBuilder内部暴露了一些未文档化的属性,可直接用来访问和修改已添加的关联查询配置,以下是具体实现方案:
核心实现思路
- 主表直接用官方API
withSchema()配置Schema; - 所有关联查询的配置都存在QueryBuilder的
_join数组中,遍历该数组为每个关联表拼接Schema前缀; - 若关联表是子查询(QueryBuilder实例),则递归调用方法为子查询添加Schema。
完整代码示例
const query = knex.from('myTable1 as t1') .select(['myCol1']) .join('myTable2 as t2', 't1.myCol1', 't2.myCol2') .join('myTable3 as t3', 't1.myCol1', 't3.myCol3') .where('t1.myCol4', 'myValue'); function addSchema(query, schema) { // 为主表添加Schema query.withSchema(schema); // 遍历所有关联查询 if (query._join) { query._join.forEach(join => { // 处理关联表为字符串的情况(带别名或不带) if (typeof join.table === 'string') { const [tableName, alias] = join.table.split(' as '); // 拼接Schema后重新组装表名(支持别名) join.table = alias ? `${schema}.${tableName} as ${alias}` : `${schema}.${tableName}`; } // 处理关联表为子查询的情况,递归添加Schema else if (join.table instanceof knex.QueryBuilder) { addSchema(join.table, schema); } }); } return query; } // 克隆原查询并分别添加不同Schema,用于构建Union const queryWithSchema1 = addSchema(query.clone(), 'mySchema1'); const queryWithSchema2 = addSchema(query.clone(), 'mySchema2'); // 生成多Schema的Union查询 const unionQuery = queryWithSchema1.union(queryWithSchema2);
注意事项
_join是Knex内部未公开的属性,当前版本稳定可用,但Knex版本升级时需注意兼容性;- 若Schema包含特殊字符(如
.),可通过反引号包裹避免语法错误,例如:\${schema}`.${tableName}`; leftJoin/rightJoin等关联类型均适用,所有关联配置都会存入_join数组。
内容的提问来源于stack exchange,提问作者Travesty3
相关产品推荐
相关产品推荐

