我正在寻找一种方法来捕获Objection.js库执行的所有查询的原始 SQL ,并将绑定插入到 SQL 字符串中。
我意识到有一个Knex 事件处理程序可以利用,但是它的第二个参数on('query', data)是一个包含 SQL 模板的对象,其中的绑定是分开的。
例如
{
sql: "select \"accounts\".* from \"accounts\" where \"id\" = ?",
bindings: [1]
}
Run Code Online (Sandbox Code Playgroud)
我想知道是否最优雅的方法是使用.toString()QueryBuilder 上存在的方法,但我认为回调中没有 QueryBuilder 的特定实例。理想情况下,我不会重新发明轮子并重新编写 Knex 的插值方法。
任何指针将不胜感激。
谢谢!
您可以使用该.toKnexQuery()函数提取底层 knex 查询构建器并获得对.toSQL()和 的访问权限.toQuery()。
我使用 Objection 的第 2 版测试并验证了以下示例。我.toKnexQuery()在版本 1 文档中找不到,因此无法验证它是否适用于早期版本的反对意见。
// Users.js
const { Model } = require('objection')
class Users extends Model {
static get tableName() { return 'users' }
// Insert jsonSchema, relationMappings, etc. here
}
module.exports = Users
Run Code Online (Sandbox Code Playgroud)
const Users = require('./path/to/Users')
const builder = Users.query()
.findById(1)
.toKnexQuery()
console.log(builder.toQuery())
// "select `users`.* from `users` where `users`.`id` = 1"
console.log(builder.toSQL())
// {
// method: 'select',
// bindings: [ 1 ],
// sql: 'select `users`.* from `users` where `users`.`id` = ?'
// }
Run Code Online (Sandbox Code Playgroud)
可能应该重申的是,除了.toString(),.toQuery()也可能容易受到 SQL 注入攻击(请参阅此处)。
一种更“负责任”的方式来修改查询可能是这样的(使用 MySQL):
const { sql, bindings } = Users.query()
.insert({ id: 1 })
.toKnexQuery()
.toSQL()
.toNative()
Users.knex().raw(`${sql} ON DUPLICATE KEY UPDATE foo = ?`, [...bindings, 'bar'])
Run Code Online (Sandbox Code Playgroud)
Knex / objection.js 不提供任何可以安全地进行插值的方法。.toString()在某些情况下可能会产生无效结果,并且它们可能容易受到 SQL 注入攻击。
如果仅用于调试目的,那么了解如何.toQuery()实现会有所帮助。https://github.com/knex/knex/blob/e37aeaa31c8ef9c1b07d2e4d3ec6607e557d800d/lib/interface.js#L12
knex.client._formatQuery(sql, bindings, tz)
Run Code Online (Sandbox Code Playgroud)
但它不是公共 API,因此即使在 knex 的补丁版本之间也不能保证相同。
| 归档时间: |
|
| 查看次数: |
2177 次 |
| 最近记录: |