如何使用 node-postgres (pg) 将此 JSONB 正确保存到 PostgreSQL 中?
How do I properly save this JSONB into PostgreSQL using node-postgres (pg)?
所以我在 GET URL 中收到了信息,这些信息需要传递到 JSON 中,然后保存在 PostgreSQL DBMS 中(与正确的递增 ID 聚合)。我写了下面的代码,它似乎没有保存任何东西而没有错误:
// Pg initialization
const { Client } = require('pg')
client = new Client({
host: 'localhost',
user: 'postgres',
password: 'passwordhere',
database: 'dbnamehere',
});
const createTableText = `
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
CREATE TEMP TABLE IF NOT EXISTS cases (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
data JSONB
);
`
app.get('/test', async function (req, res) {
data = req.query.data;
console.log(data);
res.status(200).send(data);
// create our temp table
await client.query(createTableText)
//const newUser = { email: 'test@test.com' }
// create a new case
await client.query('INSERT INTO cases(data) VALUES()', [data])
const { rows } = await client.query('SELECT * FROM cases')
console.log(rows)
res.end();
});
我的 package.json 依赖项:
"dependencies": {
"express": "^4.17.1",
"mongoose": "^5.9.9",
"pg": "^8.0.3"
},
"devDependencies": {}
更新
我在文件末尾有这个错误处理代码:
// Prints out more detailed errors
if(process.env.NODE_ENV !== 'production') {
process.once('uncaughtException', function(err) {
console.error('FATAL: Uncaught exception.');
console.error(err.stack||err);
setTimeout(function(){
process.exit(1);
}, 100);
});
}
我也尝试安装 npm install express-promise-router
并添加以下代码,但未打印任何错误:
var router = require('express-promise-router')();
router.use('/test', function (req, res) {
return Promise.reject();
})
更新2
这段代码没有关闭它打印出 JSONB,不是我如何保存它?:
const connectionString=urlhere;
const pool = new Pool({
connectionString: connectionString,
})
const client = new Client({
connectionString: connectionString,
})
client.connect()
更新3:
我删除了异步代码并使其同步。我现在收到以下错误消息:
(node:10860) UnhandledPromiseRejectionWarning: Error: Connection terminated
at Connection.<anonymous> (/path/here/node_mo
dules/pg/lib/client.js:275:34)
at Object.onceWrapper (events.js:299:28)
at Connection.emit (events.js:215:7)
at Socket.<anonymous> (/path/here/node_module
s/pg/lib/connection.js:73:10)
at Socket.emit (events.js:210:5)
at TCP.<anonymous> (net.js:659:12)
(node:10860) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This
error originated either by throwing inside of an async function without a catch
block, or by rejecting a promise which was not handled with .catch(). (rejectio
n id: 1)
(node:10860) [DEP0018] DeprecationWarning: Unhandled promise rejections are depr
ecated. In the future, promise rejections that are not handled will terminate th
e Node.js process with a non-zero exit code.
(node:10860) UnhandledPromiseRejectionWarning: Error: Connection terminated
at Connection.<anonymous> (/path/here/client.js:275:34)
at Object.onceWrapper (events.js:299:28)
at Connection.emit (events.js:215:7)
at Socket.<anonymous> (/path/here/node_module
s/pg/lib/connection.js:73:10)
at Socket.emit (events.js:210:5)
at TCP.<anonymous> (net.js:659:12)
(node:10860) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This
error originated either by throwing inside of an async function without a catch
block, or by rejecting a promise which was not handled with .catch(). (rejectio
n id: 2)
(node:10860) UnhandledPromiseRejectionWarning: Error: Connection terminated
at Connection.<anonymous> (/path/here/node_mo
dules/pg/lib/client.js:275:34)
at Object.onceWrapper (events.js:299:28)
at Connection.emit (events.js:215:7)
at Socket.<anonymous> (/path/here/node_module
s/pg/lib/connection.js:73:10)
at Socket.emit (events.js:210:5)
at TCP.<anonymous> (net.js:659:12)
(node:10860) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This
error originated either by throwing inside of an async function without a catch
block, or by rejecting a promise which was not handled with .catch(). (rejectio
n id: 3)
确保您的客户端正确连接到您的 Postgres 数据库,尝试添加一个 client.connect()
和带有控制台日志的基本查询(在您的路由器之外)。
https://node-postgres.com/features/connecting
您的表是否正确创建意味着您已连接到数据库?
NodeJS和数据库是在你的电脑上还是在docker中?
请求是否给你任何响应代码?
我有一个使用 express-generator 文件夹结构生成的项目。但它遵循 node pg suggested 项目结构。
.
├── _bin
| ├── www
├── _db
| ├── index.js
├── _server
| ├── index.js
├── _sql
| ├── create.sql
| ├── insert.sql
| └── drop.sql
├──.env
├── package.json
└── app.js
db/index.js
const { Pool } = require('pg')
const pool = new Pool()
module.exports = {
query: (text, params, callback) => {
return pool.query(text, params, callback)
},
}
在上面的文件中,凭据由 .env 文件加载。但是你可以像你的问题一样。
server/index.js
// notice here I'm requiring my database adapter file
// and not requiring node-postgres directly
const db = require('../db')
app.get('/:id', (req, res, next) => {
db.query('SELECT * FROM users WHERE id = ', [req.params.id], (err, res) => {
if (err) {
return next(err)
}
res.send(res.rows[0])
})
})
现在在 sql 文件夹中,您应该放置 DDL 数据。
sql/create.sql
CREATE TABLE employee(
employee_id SERIAL PRIMARY KEY ,
login VARCHAR(20) NOT NULL,
password VARCHAR(512)
);
在这里您可以仅使用 psql
汇总命令,或者您可以使用 javascript 创建 运行 DDL 的包装器并在您的 package.json
如果您想在 javascript
中进行包装
sql/create.js
const fs = require('fs'),
pg = require('../db/index'),
sql = fs.readFileSync(__dirname + '/../sql/create.sql').toString();
pg.query(sql, (err) => {
if (err) {
throw err;
}
})
现在,在您的 package.json 脚本部分,您可以添加一个新行:
package.json
{
...
"name": "myawesomeproject",
"version": "1.0.0",
"description": "My wonderful description",
"main": "app.js",
"scripts": {
"start": "node ./bin/www",
"createdb": "node ./sql/create.js"
},
...
}
现在您可以使用 npm run createdb
.
所以在你的 /test
路线中回答真正的问题应该是:
app.get('/test', async function (req, res) {
try {
const { rows } = await client.query('SELECT * FROM cases')
res.status(200).send(rows);
} catch {
res.status(500).send("Error. Detail: "+e)
}
});
//should insert data with post method, whole body is your current data.
app.post('/adddata', async (req, res) => {
const data = req.body;
console.log(data);
try {
await client.query('INSERT INTO cases(data) VALUES()', [data])
res.status(201).send('Data inserted');
} catch (e) {
res.status(500).send("Error. Detail: "+e)
}
})
所以我在 GET URL 中收到了信息,这些信息需要传递到 JSON 中,然后保存在 PostgreSQL DBMS 中(与正确的递增 ID 聚合)。我写了下面的代码,它似乎没有保存任何东西而没有错误:
// Pg initialization
const { Client } = require('pg')
client = new Client({
host: 'localhost',
user: 'postgres',
password: 'passwordhere',
database: 'dbnamehere',
});
const createTableText = `
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
CREATE TEMP TABLE IF NOT EXISTS cases (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
data JSONB
);
`
app.get('/test', async function (req, res) {
data = req.query.data;
console.log(data);
res.status(200).send(data);
// create our temp table
await client.query(createTableText)
//const newUser = { email: 'test@test.com' }
// create a new case
await client.query('INSERT INTO cases(data) VALUES()', [data])
const { rows } = await client.query('SELECT * FROM cases')
console.log(rows)
res.end();
});
我的 package.json 依赖项:
"dependencies": {
"express": "^4.17.1",
"mongoose": "^5.9.9",
"pg": "^8.0.3"
},
"devDependencies": {}
更新
我在文件末尾有这个错误处理代码:
// Prints out more detailed errors
if(process.env.NODE_ENV !== 'production') {
process.once('uncaughtException', function(err) {
console.error('FATAL: Uncaught exception.');
console.error(err.stack||err);
setTimeout(function(){
process.exit(1);
}, 100);
});
}
我也尝试安装 npm install express-promise-router
并添加以下代码,但未打印任何错误:
var router = require('express-promise-router')();
router.use('/test', function (req, res) {
return Promise.reject();
})
更新2 这段代码没有关闭它打印出 JSONB,不是我如何保存它?:
const connectionString=urlhere;
const pool = new Pool({
connectionString: connectionString,
})
const client = new Client({
connectionString: connectionString,
})
client.connect()
更新3:
我删除了异步代码并使其同步。我现在收到以下错误消息:
(node:10860) UnhandledPromiseRejectionWarning: Error: Connection terminated
at Connection.<anonymous> (/path/here/node_mo
dules/pg/lib/client.js:275:34)
at Object.onceWrapper (events.js:299:28)
at Connection.emit (events.js:215:7)
at Socket.<anonymous> (/path/here/node_module
s/pg/lib/connection.js:73:10)
at Socket.emit (events.js:210:5)
at TCP.<anonymous> (net.js:659:12)
(node:10860) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This
error originated either by throwing inside of an async function without a catch
block, or by rejecting a promise which was not handled with .catch(). (rejectio
n id: 1)
(node:10860) [DEP0018] DeprecationWarning: Unhandled promise rejections are depr
ecated. In the future, promise rejections that are not handled will terminate th
e Node.js process with a non-zero exit code.
(node:10860) UnhandledPromiseRejectionWarning: Error: Connection terminated
at Connection.<anonymous> (/path/here/client.js:275:34)
at Object.onceWrapper (events.js:299:28)
at Connection.emit (events.js:215:7)
at Socket.<anonymous> (/path/here/node_module
s/pg/lib/connection.js:73:10)
at Socket.emit (events.js:210:5)
at TCP.<anonymous> (net.js:659:12)
(node:10860) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This
error originated either by throwing inside of an async function without a catch
block, or by rejecting a promise which was not handled with .catch(). (rejectio
n id: 2)
(node:10860) UnhandledPromiseRejectionWarning: Error: Connection terminated
at Connection.<anonymous> (/path/here/node_mo
dules/pg/lib/client.js:275:34)
at Object.onceWrapper (events.js:299:28)
at Connection.emit (events.js:215:7)
at Socket.<anonymous> (/path/here/node_module
s/pg/lib/connection.js:73:10)
at Socket.emit (events.js:210:5)
at TCP.<anonymous> (net.js:659:12)
(node:10860) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This
error originated either by throwing inside of an async function without a catch
block, or by rejecting a promise which was not handled with .catch(). (rejectio
n id: 3)
确保您的客户端正确连接到您的 Postgres 数据库,尝试添加一个 client.connect()
和带有控制台日志的基本查询(在您的路由器之外)。
https://node-postgres.com/features/connecting
您的表是否正确创建意味着您已连接到数据库?
NodeJS和数据库是在你的电脑上还是在docker中?
请求是否给你任何响应代码?
我有一个使用 express-generator 文件夹结构生成的项目。但它遵循 node pg suggested 项目结构。
.
├── _bin
| ├── www
├── _db
| ├── index.js
├── _server
| ├── index.js
├── _sql
| ├── create.sql
| ├── insert.sql
| └── drop.sql
├──.env
├── package.json
└── app.js
db/index.js
const { Pool } = require('pg')
const pool = new Pool()
module.exports = {
query: (text, params, callback) => {
return pool.query(text, params, callback)
},
}
在上面的文件中,凭据由 .env 文件加载。但是你可以像你的问题一样。
server/index.js
// notice here I'm requiring my database adapter file
// and not requiring node-postgres directly
const db = require('../db')
app.get('/:id', (req, res, next) => {
db.query('SELECT * FROM users WHERE id = ', [req.params.id], (err, res) => {
if (err) {
return next(err)
}
res.send(res.rows[0])
})
})
现在在 sql 文件夹中,您应该放置 DDL 数据。
sql/create.sql
CREATE TABLE employee(
employee_id SERIAL PRIMARY KEY ,
login VARCHAR(20) NOT NULL,
password VARCHAR(512)
);
在这里您可以仅使用 psql
汇总命令,或者您可以使用 javascript 创建 运行 DDL 的包装器并在您的 package.json
如果您想在 javascript
中进行包装sql/create.js
const fs = require('fs'),
pg = require('../db/index'),
sql = fs.readFileSync(__dirname + '/../sql/create.sql').toString();
pg.query(sql, (err) => {
if (err) {
throw err;
}
})
现在,在您的 package.json 脚本部分,您可以添加一个新行:
package.json
{
...
"name": "myawesomeproject",
"version": "1.0.0",
"description": "My wonderful description",
"main": "app.js",
"scripts": {
"start": "node ./bin/www",
"createdb": "node ./sql/create.js"
},
...
}
现在您可以使用 npm run createdb
.
所以在你的 /test
路线中回答真正的问题应该是:
app.get('/test', async function (req, res) {
try {
const { rows } = await client.query('SELECT * FROM cases')
res.status(200).send(rows);
} catch {
res.status(500).send("Error. Detail: "+e)
}
});
//should insert data with post method, whole body is your current data.
app.post('/adddata', async (req, res) => {
const data = req.body;
console.log(data);
try {
await client.query('INSERT INTO cases(data) VALUES()', [data])
res.status(201).send('Data inserted');
} catch (e) {
res.status(500).send("Error. Detail: "+e)
}
})