如何使用 Vultr Managed Database for PostgreSQL with NodeJS

一、介绍

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

三、设置示例数据库

每个数据驱动的应用程序都需要一个数据库来永久存储数据。您需要设置示例数据库和表。在生产环境中,根据应用程序的复杂性,您可能需要多个表。按照以下步骤初始化数据库:

  1. 首先更新服务器的软件包信息索引。
    $ sudo apt update 
    
  2. 安装软件包。这是一个轻量级的客户端包,用于与托管的PostgreSQL集群进行交互,而无需在服务器上安装完整的PostgreSQL包。postgresql-client
    $ sudo apt install -y postgresql-client
    
  3. 运行以下命令以登录到托管的 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:
    
  4. 输入您的 PostgreSQL 集群数据库密码,然后按继续。然后,确保获得以下输出。ENTER

    输出。

    defaultdb=>
    
  5. 发出以下命令以创建示例数据库。company_db
    defaultdb=> CREATE DATABASE company_db;
    

    输出。

    CREATE DATABASE
    
  6. 连接到新数据库。company_db
    defaultdb=> \c company_db;
    

    输出。

    ...
    
    You are now connected to database "company_db" as user "vultradmin".
    
  7. 创建表。此表存储客户的信息。稍后,本指南将介绍如何从 Node.js 代码执行 、、 和命令以与表进行交互。customersINSERTUPDATEDELETESELECTcustomers
    company_db=> CREATE TABLE customers (
    
                     customer_id SERIAL PRIMARY KEY,
    
                     first_name VARCHAR(50),
    
                     last_name VARCHAR(50)        
    
                 );
    

    输出。

    CREATE TABLE
    
  8. 将示例数据插入表中,以确保获得正确的架构。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
    
  9. 查询以验证数据。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)
    
  10. 从托管的 PostgreSQL 数据库集群注销。
    company_db=> \q
    

设置数据库和示例表后,继续下一步以创建用于与托管 PostgreSQL 数据库集互的中央节点.js数据库模块。

四、 创建数据库网关模块

Node.js 允许您将应用程序打包到不同的模块中,以组织复杂的功能,您可以在源代码中的多个位置重用这些功能。在设计与数据库交互的 Node.js 应用程序时,通常创建中央数据库模块。稍后,您可以将此模块包含在需要访问数据库的每个文件中。按照以下步骤创建数据库网关模块:

  1. 为应用程序创建一个新目录,以将源代码与系统文件分开。project
    $ mkdir project
    
  2. 切换到新目录。project
    $ cd project
    
  3. 在文本编辑器上打开一个新文件。postgresql_gateway.js
    $ nano postgresql_gateway.js
    
  4. 在文件中输入以下信息。将 替换为正确的 PostgreSQL 数据库群集主机名和密码。postgresql_gateway.jsSAMPLE_POSTGRESQL_DB_HOST_STRING.vultrdb.comEXAMPLE_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;
    
  5. 保存并关闭文件。postgresql_gateway.js

4.1、该文件解释说postgresql_gateway.js

该文件包含一个类模块()与六种不同的方法。postgresql_gateway.jspostgresql_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

  1. connectDb():此方法使用托管 PostgreSQL 数据库集群的凭据连接到数据库,并使用语句返回可重用的客户端连接。return client;
  2. execute_query(callBack, queryString, paramValues):此方法使用该语句连接到 PostgreSQL 数据库。然后,该方法调用函数来执行不同的数据库查询。var db_client = this.connectDb();db_client.query(queryString, paramValues, ...)
  3. save_data(jsonData, callBack):此方法接受包含客户详细信息的 JSON 有效负载( 和 ),然后调用该方法以使用命令将数据保存到数据库。first_namelast_nameexecute_query(...)INSERT
  4. update_data(jsonData, callBack):此方法接受包含 的 JSON 有效负载,并查询数据库以查找匹配项。然后,该方法调用该方法以更新与 .customer_idupdate_data(...)execute_query(...)first_namelast_namecustomer_id
  5. delete_data(jsonData, callBack):此方法接受包含要删除的记录的 JSON 有效负载。然后,该方法调用该方法以将命令发送到 PostgreSQL 数据库。customer_iddelete_data(...)this.execute_query(...)DELETE
  6. query_data(customerId, callBack):此方法使用该语句从 PostgreSQL 表中获取记录。如果请求单个记录,该方法将使用以下声明将筛选器参数追加到查询。select * from customerscustomersquery_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.jspostgresql_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

  1. 在文本编辑器上打开一个新的。main.js
    $ nano main.js
    
  2. 在文件中输入以下信息。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; 
    
            }
    
    });
    
    
    
    }
    
  3. 保存并关闭文件。main.js

5.1、该文件解释说main.js

文件开头的两行加载服务器模块和自定义数据库网关模块。main.jshttppostgresql_gateway

const http = require('http');

const postgresql_gateway    = require('./postgresql_gateway.js');

...

服务器模块创建一个 Web 服务器,用于侦听端口 上的传入连接。将传入 HTTP 的委托到自定义函数。该语句告知 Web 服务器侦听定义的端口和主机上的传入请求。httplocal8080const 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 命令运行一些测试。请按照以下步骤操作:npmnpmpgcurl

  1. 确保包是最新的。npm
    $ sudo npm install npm -g
    

    输出。

    ...
    
    removed 14 packages, changed 73 packages, and audited 223 packages in 7s
    
    ...
    
  2. 使用包初始化项目。npm
    $ npm init
    
  3. 收到提示时,输入以下响应,后跟: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
    
  4. 使用该软件包为 Node.js 安装 PostgreSQL 模块。npmpg
    $ npm install pg
    

    输出。

    ...
    
    added 15 packages, and audited 16 packages in 2s
    
  5. 使用该命令运行应用程序。请记住,该文件是应用程序的入口点。nodemain.js
    $ node main.js
    

    输出。

    Server running at http://localhost:8080/
    
  6. 不要在活动终端窗口中运行任何其他命令,因为前一个命令具有阻止功能。SSH
  7. 在服务器上建立另一个会话,并运行以下 Linux 命令以向应用程序发送 HTTP 请求。SSHcurl
    • 使用 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 方法更新现有客户。对于此命令,必须定义要更新的记录的 和 和字段的新值。PUTcustomer_idfirst_namelast_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 有效负载中包含要删除的记录。DELETEcustomer_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"
      
              }
      
          ]
      
      }
      

应用程序按预期工作,您可以毫无问题地运行 、、 和 操作。SELECTINSERTUPDATEDELETE

七、结论

本指南向您展示如何实现 Node.js 模块以与 Ubuntu 20.04 服务器上的托管 PostgreSQL 数据库进行交互。尽管本指南演示了使用单个表的 PostgreSQL 思想,但您可以根据应用程序的逻辑创建其他表。托管的PostgreSQL数据库集群允许您实现云数据库应用程序,而无需任何复杂的安装和配置过程。pg

赞(0)
未经允许不得转载:主机百科 » 如何使用 Vultr Managed Database for PostgreSQL with NodeJS