为objection.js进行的所有查询打印完整的SQL



我正在寻找一种方法来捕获Objection.js库执行的所有查询的原始SQL,并将绑定插入SQL字符串中

我意识到有一个Knex事件处理程序可以利用,但on('query', data)的第二个参数是一个包含SQL模板的对象,该模板具有单独的绑定。

例如

{
sql: "select "accounts".* from "accounts" where "id" = ?",
bindings: [1]
}

我想知道最优雅的方法是否是使用QueryBuilder上存在的.toString()方法,但我认为回调中没有QueryBuilder的特定实例。理想情况下,我不会重新发明轮子,重新编写Knex的插值方法。

任何建议都将不胜感激。

谢谢!

您可以使用.toKnexQuery()函数来提取底层knex查询生成器,并获得对.toSQL().toQuery()的访问权限。

我使用版本2的异议测试并验证了以下示例。我在版本1的文档中找不到.toKnexQuery(),因此无法验证它是否适用于早期版本的异议。

// Users.js
const { Model } = require('objection')
class Users extends Model {
static get tableName() { return 'users' }
// Insert jsonSchema, relationMappings, etc. here
}
module.exports = Users
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` = ?'
// }

可能需要重申的是,除了.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'])

Knex/objection.js没有提供任何可以安全地进行插值的方法。.toString()在某些情况下会产生无效的结果,并且很容易受到sql注入攻击。

如果只是为了调试目的,那么查看.toQuery()的实现方式会有所帮助。https://github.com/knex/knex/blob/e37aeaa31c8ef9c1b07d2e4d3ec6607e557d800d/lib/interface.js#L12

knex.client._formatQuery(sql, bindings, tz)

虽然它不是一个公共的API,所以即使在knex的补丁版本之间也不能保证它是相同的。

最新更新