为 objection.js 进行的所有查询打印完整的 SQL
Print complete SQL for all queries made by objection.js
我正在寻找一种方法来为 Objection.js 库执行的所有查询捕获原始 SQL,并将绑定插入 SQL字符串.
我知道有一个 Knex event handler 可以利用,但是 on('query', data)
的第二个参数是一个包含 SQL 模板的对象,绑定是分开的。
例如
{
sql: "select \"accounts\".* from \"accounts\" where \"id\" = ?",
bindings: [1]
}
我想知道执行此操作的最优雅方法是否是使用 QueryBuilder 上存在的类似 .toString()
方法的方法,但我认为 QueryBuilder 的特定实例不可用回调。理想情况下,我不会重新发明轮子并重新编写 Knex 的插值方法。
任何指点将不胜感激。
谢谢!
Knex / objection.js 不提供任何可以安全进行插值的方法。 .toString()
在某些情况下会产生无效结果,并且它们容易受到 sql 注入攻击。
如果仅用于调试目的,查看 .toQuery()
的实现方式会有所帮助。 https://github.com/knex/knex/blob/e37aeaa31c8ef9c1b07d2e4d3ec6607e557d800d/lib/interface.js#L12
knex.client._formatQuery(sql, bindings, tz)
虽然它不是 public API,但不能保证它在 knex 的补丁版本之间是相同的。
您可以使用 .toKnexQuery()
function to pull out the underlying knex query builder and gain access to .toSQL()
和 .toQuery()
。
我使用 Objection 的版本 2 测试并验证了以下示例。我在 version 1 docs 中找不到 .toKnexQuery()
,因此无法验证它是否适用于早期版本的 Objection。
// 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 注入攻击(参见 here)。
修改查询的更“负责任”的方式可能是这样的(MySQL):
const { sql, bindings } = Users.query()
.insert({ id: 1 })
.toKnexQuery()
.toSQL()
.toNative()
Users.knex().raw(`${sql} ON DUPLICATE KEY UPDATE foo = ?`, [...bindings, 'bar'])
我正在寻找一种方法来为 Objection.js 库执行的所有查询捕获原始 SQL,并将绑定插入 SQL字符串.
我知道有一个 Knex event handler 可以利用,但是 on('query', data)
的第二个参数是一个包含 SQL 模板的对象,绑定是分开的。
例如
{
sql: "select \"accounts\".* from \"accounts\" where \"id\" = ?",
bindings: [1]
}
我想知道执行此操作的最优雅方法是否是使用 QueryBuilder 上存在的类似 .toString()
方法的方法,但我认为 QueryBuilder 的特定实例不可用回调。理想情况下,我不会重新发明轮子并重新编写 Knex 的插值方法。
任何指点将不胜感激。
谢谢!
Knex / objection.js 不提供任何可以安全进行插值的方法。 .toString()
在某些情况下会产生无效结果,并且它们容易受到 sql 注入攻击。
如果仅用于调试目的,查看 .toQuery()
的实现方式会有所帮助。 https://github.com/knex/knex/blob/e37aeaa31c8ef9c1b07d2e4d3ec6607e557d800d/lib/interface.js#L12
knex.client._formatQuery(sql, bindings, tz)
虽然它不是 public API,但不能保证它在 knex 的补丁版本之间是相同的。
您可以使用 .toKnexQuery()
function to pull out the underlying knex query builder and gain access to .toSQL()
和 .toQuery()
。
我使用 Objection 的版本 2 测试并验证了以下示例。我在 version 1 docs 中找不到 .toKnexQuery()
,因此无法验证它是否适用于早期版本的 Objection。
// 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 注入攻击(参见 here)。
修改查询的更“负责任”的方式可能是这样的(MySQL):
const { sql, bindings } = Users.query()
.insert({ id: 1 })
.toKnexQuery()
.toSQL()
.toNative()
Users.knex().raw(`${sql} ON DUPLICATE KEY UPDATE foo = ?`, [...bindings, 'bar'])