2016-12-09 53 views
0

Heroku recently posted a list of some good tips for postgres。我最受跟蹤您的查詢來源部分。我很好奇這是否可以用於Sequelize。 I know that sequelize has hooks,但不確定是否可以使用鉤子來進行實際的查詢字符串調整。Sequelize:你可以使用鉤子爲查詢添加評論嗎?

我很好奇,如果可以使用鉤子或其他Sequelize方法在Sequelize查詢中附加註釋(不使用.raw)以跟蹤查詢的調用位置。

(追加和預先計算的查詢也將是helpful for implementing row-level security,特別是set role/reset role

編輯:是否可以使用sequelize.fn()這個?

回答

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); 

3注:您還可以提交pull請求,這個功能在一個新的選項值添加到Sequelize,像options.comment,這是在查詢的末尾。

+0

謝謝你一個徹底,深思熟慮的答案。我非常感動。也許對於一些黑客來說,像'try {throw new Error(); } catch(error){console.log(error.stack); }'如果它從堆棧中選擇了正確的行,它可以工作,但會很慢;) –

相關問題