一、介绍
Vultr 提供了生产就绪的 PostgreSQL 数据库集群,您可以将其与 Node.js 一起使用来创建任务关键型应用程序。托管数据库可自动执行数据库管理中最具挑战性的方面,使你能够专注于应用。
本指南向您展示如何使用 Ubuntu 20.04 服务器上的 Node.js 库将查询传递到托管的 PostgreSQL 数据库集群。该库支持用于创建数据驱动应用程序(如参数化查询)的所有函数。pg
二、准备工作
要测试指南,请执行以下操作:
- 预配 Ubuntu 20.04 服务器。
- 创建一个非根
sudo
用户。 - 安装节点.js使用选项 2:(通过 PPA 版本安装)。
应跳过步骤 2“安装 Express.js”,因为本教程不需要 Express .js依赖项。
- 部署托管的 PostgreSQL 数据库集群。
- 导航到“概述”选项卡下的“PostgreSQL 数据库群集连接详细信息”。本指南使用以下示例连接详细信息:
- 用户名:
vultradmin
- 密码:
EXAMPLE_POSTGRESQL_PASSWORD
- 主持人:
SAMPLE_POSTGRESQL_DB_HOST_STRING.vultrdb.com
- 端口:
16751
- 用户名:
三、设置示例数据库
每个数据驱动的应用程序都需要一个数据库来永久存储数据。您需要设置示例数据库和表。在生产环境中,根据应用程序的复杂性,您可能需要多个表。按照以下步骤初始化数据库:
- 首先更新服务器的软件包信息索引。
$ sudo apt update
- 安装软件包。这是一个轻量级的客户端包,用于与托管的PostgreSQL集群进行交互,而无需在服务器上安装完整的PostgreSQL包。
postgresql-client
$ sudo apt install -y postgresql-client
- 运行以下命令以登录到托管的 PostgreSQL 集群。替换为 PostgreSQL 数据库群集的正确主机。
SAMPLE_POSTGRESQL_DB_HOST_STRING.vultrdb.com
$ psql -h SAMPLE_POSTGRESQL_DB_HOST_STRING.vultrdb.com -p 16751 -U vultradmin defaultdb
输出。
Password for user vultradmin:
- 输入您的 PostgreSQL 集群数据库密码,然后按继续。然后,确保获得以下输出。ENTER
输出。
defaultdb=>
- 发出以下命令以创建示例数据库。
company_db
defaultdb=> CREATE DATABASE company_db;
输出。
CREATE DATABASE
- 连接到新数据库。
company_db
defaultdb=> \c company_db;
输出。
... You are now connected to database "company_db" as user "vultradmin".
- 创建表。此表存储客户的信息。稍后,本指南将介绍如何从 Node.js 代码执行 、、 和命令以与表进行交互。
customers
INSERT
UPDATE
DELETE
SELECT
customers
company_db=> CREATE TABLE customers ( customer_id SERIAL PRIMARY KEY, first_name VARCHAR(50), last_name VARCHAR(50) );
输出。
CREATE TABLE
- 将示例数据插入表中,以确保获得正确的架构。
customers
company_db=> INSERT INTO customers (first_name, last_name) VALUES ('JOHN', 'DOE'); INSERT INTO customers (first_name, last_name) VALUES ('MARY', 'SMITH'); INSERT INTO customers (first_name, last_name) VALUES ('PETER', 'JONES');
输出。
... INSERT 0 1
- 查询以验证数据。
customers
company_db=> SELECT customer_id, first_name, last_name FROM customers;
输出。
customer_id | first_name | last_name -------------+------------+----------- 1 | JOHN | DOE 2 | MARY | SMITH 3 | PETER | JONES (3 rows)
- 从托管的 PostgreSQL 数据库集群注销。
company_db=> \q
设置数据库和示例表后,继续下一步以创建用于与托管 PostgreSQL 数据库集互的中央节点.js数据库模块。
四、 创建数据库网关模块
Node.js 允许您将应用程序打包到不同的模块中,以组织复杂的功能,您可以在源代码中的多个位置重用这些功能。在设计与数据库交互的 Node.js 应用程序时,通常创建中央数据库模块。稍后,您可以将此模块包含在需要访问数据库的每个文件中。按照以下步骤创建数据库网关模块:
- 为应用程序创建一个新目录,以将源代码与系统文件分开。
project
$ mkdir project
- 切换到新目录。
project
$ cd project
- 在文本编辑器上打开一个新文件。
postgresql_gateway.js
$ nano postgresql_gateway.js
- 在文件中输入以下信息。将 替换为正确的 PostgreSQL 数据库群集主机名和密码。
postgresql_gateway.js
SAMPLE_POSTGRESQL_DB_HOST_STRING.vultrdb.com
EXAMPLE_POSTGRESQL_PASSWORD
class postgresql_gateway { connectDb() { const { Client } = require('pg'); const client = new Client({ user: "vultradmin", database: "company_db", password: "EXAMPLE_POSTGRESQL_PASSWORD", port: 16751, host: "SAMPLE_POSTGRESQL_DB_HOST_STRING.vultrdb.com", ssl: { rejectUnauthorized: false } }); client.connect(); return client; } execute_query(callBack, queryString, paramValues) { var db_client = this.connectDb(); db_client.query(queryString, paramValues, (err, res) => { if (err) { callBack(err, null); } else { callBack(null, res.rows); } db_client.end(); }) ; } save_data(jsonData, callBack) { var paramValues = []; paramValues.push(jsonData.first_name); paramValues.push(jsonData.last_name); var queryString = "insert into customers (first_name, last_name) values ($1, $2) RETURNING customer_id, first_name, last_name"; this.execute_query(callBack, queryString, paramValues); } update_data(jsonData, callBack) { var paramValues = []; paramValues.push(jsonData.first_name); paramValues.push(jsonData.last_name); paramValues.push(jsonData.customer_id); var queryString = "update customers set first_name = $1, last_name = $2 where customer_id = $3 RETURNING customer_id, first_name, last_name"; this.execute_query(callBack, queryString, paramValues); } delete_data(jsonData, callBack) { var paramValues = []; paramValues.push(jsonData.customer_id); var queryString = "delete from customers where customer_id = $1 RETURNING customer_id, first_name, last_name"; this.execute_query(callBack, queryString, paramValues); } query_data(customerId, callBack) { var queryString = "select * from customers"; var paramValues = []; if (customerId != "") { queryString += " where customer_id = $1"; paramValues.push(customerId); } this.execute_query(callBack, queryString, paramValues) } } module.exports = postgresql_gateway;
- 保存并关闭文件。
postgresql_gateway.js
4.1、该文件解释说postgresql_gateway.js
该文件包含一个类模块()与六种不同的方法。postgresql_gateway.js
postgresql_gateway
class postgresql_gateway {
connectDb() {
...
}
execute_query(callBack, queryString, paramValues) {
...
}
save_data(jsonData, callBack) {
...
}
update_data(jsonData, callBack) {
...
}
delete_data(jsonData, callBack) {
...
}
query_data(customerId, callBack) {
...
}
}
module.exports = postgresql_gateway;
类模块中的六个方法执行以下功能:postgresql_gateway
connectDb()
:此方法使用托管 PostgreSQL 数据库集群的凭据连接到数据库,并使用语句返回可重用的客户端连接。return client;
execute_query(callBack, queryString, paramValues)
:此方法使用该语句连接到 PostgreSQL 数据库。然后,该方法调用函数来执行不同的数据库查询。var db_client = this.connectDb();
db_client.query(queryString, paramValues, ...)
save_data(jsonData, callBack)
:此方法接受包含客户详细信息的 JSON 有效负载( 和 ),然后调用该方法以使用命令将数据保存到数据库。first_name
last_name
execute_query(...)
INSERT
update_data(jsonData, callBack)
:此方法接受包含 的 JSON 有效负载,并查询数据库以查找匹配项。然后,该方法调用该方法以更新与 .customer_id
update_data(...)
execute_query(...)
first_name
last_name
customer_id
delete_data(jsonData, callBack)
:此方法接受包含要删除的记录的 JSON 有效负载。然后,该方法调用该方法以将命令发送到 PostgreSQL 数据库。customer_id
delete_data(...)
this.execute_query(...)
DELETE
query_data(customerId, callBack)
:此方法使用该语句从 PostgreSQL 表中获取记录。如果请求单个记录,该方法将使用以下声明将筛选器参数追加到查询。select * from customers
customers
query_data()
... if (customerId != "") { queryString += " where customer_id = $1"; paramValues.push(customerId); } ...
SQL 语句末尾的语句允许您检索受影响行的字段值。RETURNING customer_id, first_name, last_name
文件末尾的语句允许您使用以下声明在其他 Node.js 文件中导入和使用模块。module.exports = postgresql_gateway;
postgresql_gateway.js
postgresql_gateway
const postgresql_gateway = require('./postgresql_gateway.js');
var dg = new postgresql_gateway();
dg.save_data(JSON.parse(json_payload), callBack);
dg.update_data(JSON.parse(json_payload), callBack);
dg.delete_data(JSON.parse(json_payload), callBack);
dg.query_data(customerId, callBack);
模块现已准备就绪。按照下一步创建应用程序的入口点。postgresql_gateway
五、创建应用程序的入口点
每个 Node.js 应用程序都需要一个入口点。这是启动应用程序时运行的文件。本指南使用该文件来执行应用程序。请按照以下步骤创建文件:main.js
- 在文本编辑器上打开一个新的。
main.js
$ nano main.js
- 在文件中输入以下信息。
main.js
const http = require('http'); const postgresql_gateway = require('./postgresql_gateway.js'); const hostname = 'localhost'; const port = 8080; const server = http.createServer(httpHandler); server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); }); function httpHandler(req, res) { var dg = new postgresql_gateway(); var json_payload = ""; req.on('data', function (data) { json_payload += data; }); req.on('end', function () { function callBack(err, result) { var response = {}; if (err) { response.error = err.message; } else { response.data = result; } res.write(JSON.stringify(response, null, 4)); res.end(); } switch (req.method) { case "POST": dg.save_data(JSON.parse(json_payload), callBack); break; case "PUT": dg.update_data(JSON.parse(json_payload), callBack); break; case "DELETE": dg.delete_data(JSON.parse(json_payload), callBack); break; case "GET": const url = require('url'); const queryparams = url.parse(req.url, true).query; var customerId = ""; if (queryparams.customer_id) { customerId = queryparams.customer_id } dg.query_data(customerId, callBack); break; } }); }
- 保存并关闭文件。
main.js
5.1、该文件解释说main.js
文件开头的两行加载服务器模块和自定义数据库网关模块。main.js
http
postgresql_gateway
const http = require('http');
const postgresql_gateway = require('./postgresql_gateway.js');
...
服务器模块创建一个 Web 服务器,用于侦听端口 上的传入连接。将传入 HTTP 的委托到自定义函数。该语句告知 Web 服务器侦听定义的端口和主机上的传入请求。http
local
8080
const server = http.createServer(httpHandler);
httpHandler(){...}
server.listen(port, hostname, ..);
const hostname = 'localhost';
const port = 8080;
const server = http.createServer(httpHandler);
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
该函数运行应用程序的大部分逻辑。httpHandler(req, res) {..}
在该函数下,您将使用该语句创建新的数据库网关对象。httpHandler()
var dg = new postgresql_gateway();
以下声明允许您在创建新客户、更新客户详细信息和从数据库中删除客户时从 HTTP 客户端的请求中捕获 JSON 有效负载。
...
var json_payload = "";
req.on('data', function (data) {
json_payload += data;
});
...
在该函数下,您将定义一个函数,该函数在每次向服务器发出 HTTP 请求时触发。然后,使用 Node.js 语句来评估 HTTP 方法并将 HTTP 请求路由到相应的数据库函数。req.on(...){...}
callBack(err, result)
switch (req.method) {...}
req.on('end', function () {
function callBack(err, result) {
...
res.write(JSON.stringify(response, null, 4));
res.end();
}
switch (req.method) {
...
}
}
以下列表显示了应用程序的 HTTP 请求方法以及运行请求的匹配数据库函数。
POST
:运行方法。dg.save_data(JSON.parse(json_payload), callBack);
PUT
:运行方法。dg.update_data(JSON.parse(json_payload), callBack);
DELETE
:运行方法。dg.delete_data(JSON.parse(json_payload), callBack);
GET
:运行方法。dg.query_data(customerId, callBack);
设置所有必需的 Node.js 源代码文件后,继续执行下一步以测试应用程序。
六、测试节点 .js和 PostgreSQL 应用程序
本指南的最后一步是使用 Node.js 模块初始化和设置项目的属性。然后,使用该模块安装模块并使用 Linux 命令运行一些测试。请按照以下步骤操作:npm
npm
pg
curl
- 确保包是最新的。
npm
$ sudo npm install npm -g
输出。
... removed 14 packages, changed 73 packages, and audited 223 packages in 7s ...
- 使用包初始化项目。
npm
$ npm init
- 收到提示时,输入以下响应,后跟:ENTER
package name: (project) : ENTER version: (1.0.0) : ENTER description: Node.js and PostgreSQL application ENTER entry point: (main.js) ENTER test command: ENTER git repository: ENTER keywords: node.js, postgresql ENTER author: test author ENTER license: (ISC) ENTER ... About to write to /home/francis/project/package.json: {...} Is this OK? (yes) yes ENTER
- 使用该软件包为 Node.js 安装 PostgreSQL 模块。
npm
pg
$ npm install pg
输出。
... added 15 packages, and audited 16 packages in 2s
- 使用该命令运行应用程序。请记住,该文件是应用程序的入口点。
node
main.js
$ node main.js
输出。
Server running at http://localhost:8080/
- 不要在活动终端窗口中运行任何其他命令,因为前一个命令具有阻止功能。
SSH
- 在服务器上建立另一个会话,并运行以下 Linux 命令以向应用程序发送 HTTP 请求。
SSH
curl
- 使用 HTTP 命令检索所有客户:
GET
$ curl -X GET http://127.0.0.1:8080
输出。
{ "data": [ { "customer_id": 1, "first_name": "JOHN", "last_name": "DOE" }, { "customer_id": 2, "first_name": "MARY", "last_name": "SMITH" }, { "customer_id": 3, "first_name": "PETER", "last_name": "JONES" } ] }
- 通过在 URL 中附加 来检索特定客户。
customer_id
$ curl -X GET http://127.0.0.1:8080?customer_id=2
输出。
{ "data": [ { "customer_id": 2, "first_name": "MARY", "last_name": "SMITH" } ] }
- 使用 HTTP 命令和包含客户详细信息的 JSON 有效负载创建新客户。
POST
$ curl -X POST http://127.0.0.1:8080/ -H 'Content-Type: application/json' -d '{"first_name" : "HENRY", "last_name" : "ALLAN"}'
输出。
{ "data": [ { "customer_id": 4, "first_name": "HENRY", "last_name": "ALLAN" } ] }
- 使用 HTTP 方法更新现有客户。对于此命令,必须定义要更新的记录的 和 和字段的新值。
PUT
customer_id
first_name
last_name
$ curl -X PUT http://127.0.0.1:8080/ -H 'Content-Type: application/json' -d '{"customer_id" : 4, "first_name" : "FRED", "last_name" : "ALEX"}'
输出。
{ "data": [ { "customer_id": 4, "first_name": "FRED", "last_name": "ALEX" } ] }
- 使用 HTTP 命令删除客户。在 JSON 有效负载中包含要删除的记录。
DELETE
customer_id
$ curl -X DELETE http://127.0.0.1:8080/ -H 'Content-Type: application/json' -d '{"customer_id" : 4}'
输出。
{ "data": [ { "customer_id": 4, "first_name": "FRED", "last_name": "ALEX" } ] }
- 使用 HTTP 命令检索所有客户:
应用程序按预期工作,您可以毫无问题地运行 、、 和 操作。SELECT
INSERT
UPDATE
DELETE
七、结论
本指南向您展示如何实现 Node.js 模块以与 Ubuntu 20.04 服务器上的托管 PostgreSQL 数据库进行交互。尽管本指南演示了使用单个表的 PostgreSQL 思想,但您可以根据应用程序的逻辑创建其他表。托管的PostgreSQL数据库集群允许您实现云数据库应用程序,而无需任何复杂的安装和配置过程。pg