【问题标题】:Adding a raw select statement to the Knex query builder将原始选择语句添加到 Knex 查询构建器
【发布时间】:2020-06-12 18:17:12
【问题描述】:

使用 Knex 对我的 Postgres 数据库进行查询。我有一个使用 Knex QueryBuilder 提供“基本”查询的函数。在我需要向 SELECT 语句添加原始内容之前,这可以正常工作。据我所知,运行.raw 总是希望返回一个结果。不过,我只需要将它添加到 QueryBuilder 中,这样它就可以由我的应用程序的不同部分执行。

const baseQuery = knex
    .select(newUserFields)
    .from('users')
    .leftJoin('user_roles', 'users.id', 'user_roles.user_id')
    .leftJoin('roles', 'user_roles.role_id', 'roles.id')
    .leftJoin('role_permissions', 'roles.id', 'role_permissions.role_id')
    .leftJoin(
        'permissions',
        'permissions.id',
        'role_permissions.permission_id'
    )
    .groupBy(
        'users.id',
        'users.email',
        'users.name',
        'users.status',
        'users.created_at',
        'users.password_reset_expiration',
        'users.password',
        'users.password_reset_token'
    )
    .orderBy('users.created_at', 'desc');

我需要在选择中添加以下内容:

knex.raw('to_json(array_agg(distinct roles.name)) as roleNames')
knex.raw('to_json(array_agg(distinct permissions.name)) as permissionNames')

如何将这些原始选择添加到基本查询中,以便可以将基本查询作为 QueryBuilder 传递给不同的函数并添加到?

【问题讨论】:

    标签: node.js postgresql knex.js


    【解决方案1】:

    knex 很酷的地方在于它是一个queryBuilder,它允许您调用方法而不受调用顺序 的任何限制。这意味着您可以在函数中构建基本查询,然后将其他内容附加到它(例如附加列)。

    在您的情况下,您只需调用另一个时间来选择(knex 将加入选择调用)

    // base-query.js
    export const getBaseQuery = () => knex
      .select(newUserFields)
      .from('users')
      .leftJoin('user_roles', 'users.id', 'user_roles.user_id')
      .leftJoin('roles', 'user_roles.role_id', 'roles.id')
      .leftJoin('role_permissions', 'roles.id', 'role_permissions.role_id')
      .leftJoin('permissions', 'permissions.id', 'role_permissions.permission_id')
      .groupBy(
        'users.id',
        'users.email',
        'users.name',
        'users.status',
        'users.created_at',
        'users.password_reset_expiration',
        'users.password',
        'users.password_reset_token'
      )
      .orderBy('users.created_at', 'desc');
    
    // other-file.js
    import {getBaseQuery} from 'base-query';
    
    const enhancedQuery = getBaseQuery().select([
      knex.raw('to_json(array_agg(distinct roles.name)) as roleNames'),
      knex.raw('to_json(array_agg(distinct permissions.name)) as permissionNames'),
    ]);
    
    const results = await enhancedQuery;
    

    我正在大量使用的另一种很酷的方法,解决了以下要求:有时我需要从外部更改内部查询,我使用modify 例如,我有一个getProducts 方法,它执行select 查询并进行一些数据转换。 为了实现需要返回相同数据结构getProductById(只需要过滤基本查询),我传递了一个修改原始查询的queryModifier方法。

    
    async function getProducts(queryModifier) {
      const products = await knex
        .select('*')
        .from('products')
        .modify((queryBuilder) => {
          if (typeof queryModifier === 'function') {
            return queryModifier(queryBuilder);
          }
        });
    
      return products.map(someDataTransformation);
    }
    
    async function getProductById(id) {
      return getProducts((qb) => {
        return qb.where('id', id);
      });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-31
      • 2020-09-29
      • 1970-01-01
      • 2020-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多