【问题标题】:How to always filter on a column by default in Knex / Postgres?默认情况下,如何在 Knex / Postgres 中始终过滤列?
【发布时间】:2020-01-31 04:58:08
【问题描述】:

当我们删除数据时,我们通常不会删除数据库行,而是设置一个 date_deleted 列(用于非隐私敏感数据),以便稍后在必要时访问数据以进行审计。

我们如何使用 Objection、Knex 或 Postgres 始终对该列进行预过滤(如果存在),否则返回所有行? (我们只想手动查看这些列,而不是通过代码。)

看起来postProcessResponse 在 Knex 中可以正常工作 - 我们只是过滤返回的行,检查 date_deleted。但是,如果我们能找到一种方法来始终在查询触发之前而不是在获得结果之后进行过滤,那么这当然会更有效。

【问题讨论】:

    标签: database postgresql knex.js objection.js


    【解决方案1】:

    使用postProcessResponse会给你带来各种分页等问题。

    您可以使用start 事件来修改每个查询:

    knex.on('start', function(builder) {
        builder.whereNull('date_deleted')
    });
    
    knex.select('*')
      .from('users')
      .then(function(Rows) {
        //Only contains Rows where date_deleted is null
      });
    

    但这也很容易出错,例如,如果您在查询中使用.orWhere 或任何其他非普通选择的查询...

    您正在寻找的功能用knex 来实现并不方便。例如objection.js 有更多的选择。

    对于 knex,我可能只是用特殊功能扩展查询构建器,它会做这样的事情(从 knex 0.19.1 开始):

    const Knex = require('knex');
    
    Knex.QueryBuilder.extend('selectWithoutDeleted', function(tableName) {
      return this
        .with('tableWithoutDeleted',
          knex(tableName).whereNull('date_deleted')
        )
        .from('tableWithoutDeleted');
    });
    
    const res = await knex.selectWithoutDeleted('table')
      .where('col1', 'foo')
      .orWhere('col2', 'bar');
    

    理论上应该可行... CTE 首先将结果限制为不包含已删除的行,其余的 where 子句将应用于该受限结果集。

    【讨论】:

    • 对反对的最佳实践发表评论?我们也在使用那个库,但一直在考虑是否还需要它。我们有一些想法,但也想在外面听到。 (更新的问题。)
    • 在 objection.js 中,您可以为类实现例如 toJson() 方法以将其过滤掉。我不确定在您的情况下哪个是最佳实践,但一种可能性是扩展查询构建器以始终将选择包装到 CTE 事物并限制可以执行哪种查询,除非某些特殊的 .noFilter() 构建器方法叫做。在 objection.js 频道中的 gitter 中,人们可以提供更适合您的情况的更好的解决方案。
    猜你喜欢
    • 2013-07-17
    • 2021-02-24
    • 2010-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多