【发布时间】:2020-04-11 15:16:51
【问题描述】:
修改后的问题
我已经修改了问题,希望得到更清晰的答案。
我正在尝试根据传入的req.body 和表中的现有数据处理 ExpressJS 中的数据。
我收到了一个req.body,其中包含更新字段的 JSON 列表。其中一些字段在 Postgres 中存储为 JSONB。如果传入字段是 JSONB,则发出请求的表单(外部代码)已经运行 jsonpatch.compare() 以生成补丁列表,并且传入的是这些补丁而不是完整值。对于任何非 JSONB 值,传入的值只需要传递给 UPDATE 查询。
我有一个工作版本,如下所示,它假装表中现有的 JSONB 值是 NULL。显然,这不是所需要的。我需要从数据库中提取值。 non-querying-of-current-values 版本和最低限度的路由器,如下所示:
const express = require('express')
const bodyParser = require('body-parser')
const SQL = require('sql-template-strings')
const { Client } = require('pg')
const dbConfig = require('../db')
const jsonpatch = require('fast-json-patch')
const FormRouter = express.Router()
I have some update code:
````javascript
const patchFormsRoute = (req, res) => {
const client = new Client(dbConfig)
const { id } = req.body
const parts = []
const params = [id]
// list of JSONB fields for the 'forms' table
const jsonFields = [
'sections',
'editors',
'descriptions',
]
// list of all fields, including JSONB fields in the 'forms' table
const possibleFields = [
'status',
'version',
'detail',
'materials',
...jsonFields,
]
// this is a DUMMY RECORD instead of the result of a client.query
let currentRecord = { 'sections':[], 'editors':[], 'descriptions':[] }
possibleFields.forEach(myProp => {
if (req.body[myProp] != undefined) {
parts.push(`${myProp} = $${params.length + 1}`)
if (jsonFields.indexOf(myProp) > -1) {
val = currentRecord[myProp]
jsonpatch.applyPatch(val, req.body[myProp])
params.push(JSON.stringify(val))
} else {
params.push(req.body[myProp])
}
}
})
const updateQuery = 'UPDATE forms SET ' + parts.join(', ') + ' WHERE id = $1'
client.connect()
return client
.query(updateQuery, params)
.then(result => res.status(200).json(result.rowCount))
.catch(err => res.status(400).json(err.severity))
.then(() => client.end())
}
FormRouter.route('/')
.patch(bodyParser.json({ limit: '50mb' }), patchFormsRoute)
exports.FormRouter = FormRouter
我保证,这是工作代码,几乎满足了我的需求。但是,我想用表中已有的数据替换虚拟记录,同时获取。我的问题是因为多个客户端可能同时更新一行(但查看 JSONB 值的正交元素),我需要获取、计算和更新作为单个事务发生。我的计划是:
开始交易
根据传入的
id查询 Postgres 的当前行值对于任何 JSONB 字段,应用补丁以在 UPDATE 语句中为该字段生成正确的值。
使用适当的参数值运行 UPDATE 语句(来自
req.body或修补的行,具体取决于字段是否为 JSONB)COMMIT 事务,或 ROLLBACK 错误。
我已经尝试实施来自@midrizi 的答案;也许只有我一个人,但是等待和res 的简单测试相结合将服务器发送到超空间......并以超时结束。
【问题讨论】:
-
为什么在 catch 后面有一个
then? -
确保无论发生什么都关闭客户端
标签: node.js postgresql async-await node-postgres