Sequelize:你可以使用钩子为查询添加评论吗?

时间:2016-12-09 23:04:00

标签: javascript node.js orm sequelize.js

Heroku recently posted a list of some good tips for postgres跟踪您的查询源部分让我最为沉溺。我很好奇这是否可以与Sequelize一起使用。 I know that sequelize has hooks,但不确定钩子是否可用于进行实际的查询字符串调整。

我很好奇是否可以使用钩子或其他Sequelize方法将注释附加到Sequelize查询(不使用.raw)来跟踪调用查询的位置。

(对查询的追加和前置也是helpful for implementing row-level security,具体为set role / reset role

编辑:是否可以使用sequelize.fn()

1 个答案:

答案 0 :(得分:1)

如果您只想插入"标记"在SQL查询中,您可以使用Sequelize.literal()将文字字符串传递给查询生成器。将其添加到options.attributes.include会添加它,但是它还需要一个别名,因此您也必须传递某种值。

 Model.findById(id, {
   attributes: {
     include: [
       [Sequelize.literal('/* your comment */ 1'), 'an_alias'],
     ],
   },
 });

这会产生SQL

SELECT `model`.`id`, /* your comment */ 1 as `an_alias`
FROM `model` as `model`
WHERE `model`.`id` = ???

我尝试自动化这一点,它可能超出了这个答案的范围,但您可以在使用Sequelize.Model.prototype创建连接之前修改new Sequelize()以调整方法的处理。您需要为所有想要的方法执行此操作"标记"。

 // alias findById() so we can call it once we fiddle with the input
 Sequelize.Model.prototype.findById_untagged = Sequelize.Model.prototype.findById;

 // override the findbyId() method so we can intercept the options.
 Sequelize.Model.prototype.findById = function findById(id, options) {
   // get the caller somehow (I was having trouble accessing the call stack properly)
   const caller = ???;

   // you need to make sure it's defined and you aren't overriding settings, etc
   options.attributes.include.push([Sequelize.literal('/* your comment */ 1'), 'an_alias']);

   // pass it off to the aliased method to continue as normal
   return this.findById_untagged(id, options);
 }

 // create the connection
 const connection = new Sequelize(...);

注意:可能无法自动执行此操作,因为Sequelize具有use strict,因此无法访问arguments.callerarguments.callee属性。

第二个注意事项:如果您不关心修改Sequelize.Model原型,您还可以抽象调用Sequelize方法,并在那里调整选项。

function Wrapper(model) {
  return {
    findById(id, options) {
      // do your stuff
      return model.findById(id, options);
    },
  };
}

Wrapper(Model).findById(id, options);

第三次注意:您还可以提交一个拉取请求,将此功能添加到Sequelize下的新选项值,例如options.comment,该值在最后添加查询。