alj*_*zen 4 postgresql node.js sequelize.js typescript
我有我的两个模型Foo和Bar。Foo有一个 field barId,因此有一个Bar与之关联的对象。我可以查询所有Foo对象并包含它们的关联Bar对象(我将 TypeScript 与sequelize-typescript一起使用):
Foo.findAll<Foo>({
include: [{ model: Bar }]
});
Run Code Online (Sandbox Code Playgroud)
Barjsonb_field对象有一个带有结构的JSONB 字段
{ inner_field1: 'some text', inner_field2: 'some more text' }
Run Code Online (Sandbox Code Playgroud)
我可以查询Bar对象并按inner_field1如下方式进行过滤:
Bar.findAll<Bar>({
where: { 'jsonb_field': { inner_field1: 'text to find' } }
});
Run Code Online (Sandbox Code Playgroud)
这会产生以下 SQL 查询:
SELECT ... FROM "Bar" AS "Bar"
WHERE ("Bar"."jsonb_field"#>>'{inner_field1}') = 'text to find'
Run Code Online (Sandbox Code Playgroud)
到目前为止,一切都很好。现在让我们尝试查询Foo对象,包括Bar对象并按以下条件过滤inner_field1:
Foo.findAll<Foo>({
where: { '$bar.jsonb_field$': { inner_field1: 'text to find' } },
include: [{ model: Bar }]
});
Run Code Online (Sandbox Code Playgroud)
现在这会引发异常:
Error: Invalid value [object Object]
at Object.escape ({project_root}\node_modules\sequelize\lib\sql-string.js:50:11)
at Object.escape ({project_root}\node_modules\sequelize\lib\dialects\abstract\query-generator.js:917:22)
at Object.whereItemQuery ({project_root}\node_modules\sequelize\lib\dialects\abstract\query-generator.js:2095:41)
at _.forOwn ({project_root}\node_modules\sequelize\lib\dialects\abstract\query-generator.js:1937:25)
...
Run Code Online (Sandbox Code Playgroud)
作为记录,我正确包含了 Bar 对象,因为我可以按其他非 JSONB 属性进行过滤,如下所示:
Foo.findAll<Foo>({
where: { '$bar.number_field$': 5 },
include: [{ model: Bar }]
});
Run Code Online (Sandbox Code Playgroud)
据我所知,问题在于 Sequelize 不知道 的类型,jsonb_field因此当对象传递到 where 查询时它会抛出错误。
有没有办法解决这个错误,也许使用sequelize.literal()or sequelize.json()?
用途sequelize.cast及$contains操作者:
Foo.findAll<Foo>({
where: { '$bar.jsonb_field$': {
$contains: sequelize.cast('{ "inner_field1": "text to find" }', 'jsonb')
},
include: [{ model: Bar }]
});
Run Code Online (Sandbox Code Playgroud)
或者按照您的建议使用sequelize.literal:
Foo.findAll<Foo>({
where: { '$bar.jsonb_field$': {
$contains: sequelize.literal(`'{ "inner_field1": "text to find" }'::json`)
},
include: [{ model: Bar }]
});
Run Code Online (Sandbox Code Playgroud)
这两种解决方案都容易受到SQL 注入的攻击,以确保转义或删除所有可能导致问题的字符("、、'...)
是的,我刚刚回答了我自己的问题。不客气。
| 归档时间: |
|
| 查看次数: |
10268 次 |
| 最近记录: |