我有两个模型Foo
和Bar
。 Foo
有一个字段barId
,因此有一个Bar
对象与之关联。
我可以查询我的所有Foo
个对象并将其关联的Bar
对象包含在内(我使用的是带有sequelize-typescript的TypeScript):
Foo.findAll<Foo>({
include: [{ model: Bar }]
});
Bar
对象具有结构
jsonb_field
{ inner_field1: 'some text', inner_field2: 'some more text' }
我可以查询Bar
个对象并按inner_field1
进行过滤:
Bar.findAll<Bar>({
where: { 'jsonb_field': { inner_field1: 'text to find' } }
});
这会生成以下SQL查询:
SELECT ... FROM "Bar" AS "Bar"
WHERE ("Bar"."jsonb_field"#>>'{inner_field1}') = 'text to find'
到目前为止一切顺利。现在让我们尝试查询Foo
个对象,包括Bar
个对象并按inner_field1
过滤:
Foo.findAll<Foo>({
where: { '$bar.jsonb_field$': { inner_field1: 'text to find' } },
include: [{ model: Bar }]
});
现在这引发了一个异常:
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)
...
为了记录,我正确地包含了Bar对象,因为我可以按照其他非JSONB属性进行过滤:
Foo.findAll<Foo>({
where: { '$bar.number_field$': 5 },
include: [{ model: Bar }]
});
据我所知,问题在于Sequelize没有意识到jsonb_field
的类型,因此在将对象传递给where查询时会抛出错误。
是否可以解决此错误,可能使用sequelize.literal()
或sequelize.json()
?
答案 0 :(得分:0)
使用Kukodas-MBP:~ kukodajanos$ ./oc new-app nodejs~git@bitbucket.org:j4nos/nodejs.git --name mysite
--> Found image cd02d02 (3 weeks old) in image stream "openshift/nodejs" under tag "6" for "nodejs"
Node.js 6
---------
Node.js 6 available as docker container is a base platform for building and running various Node.js 6 applications and frameworks. Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.
Tags: builder, nodejs, nodejs6
* A source build using source code from ssh://git@bitbucket.org/j4nos/nodejs.git will be created
* The resulting image will be pushed to image stream "mysite:latest"
* Use 'start-build' to trigger a new build
* This image will be deployed in deployment config "mysite"
* Port 8080/tcp will be load balanced by service "mysite"
* Other containers can access this service through the hostname "mysite"
--> Creating resources ...
imagestream "mysite" created
buildconfig "mysite" created
deploymentconfig "mysite" created
和sequelize.cast
运营商:
$contains
或者按照您的建议使用Foo.findAll<Foo>({
where: { '$bar.jsonb_field$': {
$contains: sequelize.cast('{ "inner_field1": "text to find" }', 'jsonb')
},
include: [{ model: Bar }]
});
执行此操作:
sequelize.literal
这两个解决方案都容易受SQL Injections攻击,以确保转义或删除可能导致问题的所有字符(Foo.findAll<Foo>({
where: { '$bar.jsonb_field$': {
$contains: sequelize.literal(`'{ "inner_field1": "text to find" }'::json`)
},
include: [{ model: Bar }]
});
,"
,...)
是的,我刚刚回答了我自己的问题。不客气。