knex: Postgresql update + joins, from clause missing
Hi,
I hope to rewrite a raw SQL UPDATE/JOINS request to Knex style, but I have an issue with knex : The knex raw request (works well) :
knex.raw("UPDATE barcodes_products B SET bar_code = $6, modify_date = now() " +
"FROM catalogs_stores S " +
" INNER JOIN catalogs C on (S.catalog_id = C.catalog_id AND S.company_id = C.company_id AND C.status = 1) " +
" INNER JOIN catalogsversion R on (R.catalog_id = C.catalog_id AND R.status = 1) " +
" INNER JOIN catalogsversion_products V on (R.catalogversion_id = V.catalogversion_id AND C.catalog_id = R.catalog_id AND V.status = 1) " +
" INNER JOIN products P on (V.product_id = P.product_id AND V.company_id = P.company_id AND P.status = 1) " +
"WHERE S.store_id_ref = $1 " +
" AND S.status = 1 " +
" AND C.catalog_id = $2 " +
" AND V.catalogversion_id = $3 " +
" AND R.valid_from < now() " +
" AND (R.valid_until IS NULL OR R.valid_until > now()) " +
" AND P.product_id = $4 " +
" AND B.bar_code = $5 " +
" AND P.purchase_ok = true " +
" AND P.product_id = B.product_id " +
" AND P.company_id = B.company_id " +
" AND B.status = 1",
[store, catalog, version, product, barcode_current, barcode_new]
)
.exec(cb);
The Knex rewrited “style” request :
knex('barcodes_products AS B')
.from('catalogs_stores AS S')
.innerJoin('catalogs AS C', function () {
this.on('S.catalog_id', 'C.catalog_id');
this.andOn('S.company_id', 'C.company_id');
this.andOn('C.status', 1);
})
.innerJoin('catalogsversion AS R', function () {
this.on('R.catalog_id', 'C.catalog_id');
this.andOn('R.status', 1);
})
.innerJoin('catalogsversion_products AS V', function () {
this.on('R.catalogversion_id', 'V.catalogversion_id');
this.andOn('R.catalog_id', 'V.catalog_id');
this.andOn('V.status', 1);
})
.innerJoin('products AS P', function () {
this.on('P.product_id', 'V.product_id');
this.andOn('P.company_id', 'V.company_id');
this.andOn('P.status', 1);
})
.where({
'S.store_id_ref': store,
'C.catalog_id': catalog,
'V.catalogversion_id': version,
'P.product_id': product,
'B.barcode': barcode_current
})
.andWhere('P.purchase_ok', true)
.andWhere('B.status', 1)
.andWhere('P.product_id', 'B.product_id')
.andWhere('P.company_id', 'B.company_id')
.andWhere('R.valid_from', '<', 'now()')
.andWhere(function () {
this.whereNull('R.valid_until');
this.orWhere('R.valid_until', '>', 'now()');
}).update({
'bar_code': barcode_new,
'modify_date': 'now()'
})
.exec(cb);
}
Knex generated this SQL statement :
update "catalogs_stores" as "S" set "bar_code" = $1, "modify_date" = $2 where "S"."store_id_ref" = $3 and "C"."catalog_id" = $4 and "V"."catalogversion_id" = $5 and "P"."product_id" = $6 and "B"."barcode" = $7 and "P"."purchase_ok" = $8 and "B"."status" = $9 and "P"."product_id" = $10 and "P"."company_id" = $11 and "R"."valid_from" < $12 and ("R"."valid_until" is null or "R"."valid_until" > $13)
Postgresql respond: missing FROM-clause entry for table "C"
About this issue
- Original URL
- State: closed
- Created 10 years ago
- Reactions: 2
- Comments: 16 (6 by maintainers)
Commits related to this issue
- feat(postgres): add support for UPDATE FROM Closes #557 — committed to joelmukuthu/knex by joelmukuthu 6 years ago
- feat(postgres): add support for UPDATE FROM Closes tgriesser/knex#557 — committed to joelmukuthu/knex by joelmukuthu 6 years ago
@bendrucker @tgriesser Any updates on this issue? This seems to be a pretty common use case, resorting to raw queries makes me doubt the use for knex.
Same problem for me : I need to check a value into db before the update. I’ve hoped i won’t be forced to do 2 queries but with this issue, I have no choice 😢:
should return