如何在Ubuntu20.04上将PostgreSQL与Node.js一起使用
作者选择 女工程师协会 作为 Write for DOnations 计划的一部分接受捐赠。
介绍
Node.js 生态系统提供了一组与数据库交互的工具。 这些工具之一是 node-postgres,它包含允许 Node.js 与 PostgreSQL 数据库交互的模块。 使用 node-postgres
,您将能够编写可以访问和存储 PostgreSQL 数据库中的数据的 Node.js 程序。
在本教程中,您将使用 node-postgres
连接和查询 PostgreSQL(简称 Postgres)数据库。 首先,您将在 Postgres 中创建一个数据库用户和数据库。 然后,您将使用 node-postgres
模块将您的应用程序连接到 Postgres 数据库。 之后,您将使用 node-postgres
在 PostgreSQL 数据库中插入、检索和修改数据。
先决条件
要完成本教程,您需要:
- 具有
sudo
权限的非 root 用户帐户并在 Ubuntu 20.04 上启用了防火墙。 按照我们的教程 Initial Server Setup with Ubuntu 20.04 来设置您的服务器。 - Node.js 安装在 Ubuntu 上。 如果您没有安装 Node.js,请按照 如何在 Ubuntu 20.04 上安装 Node.js。
- PostgreSQL 安装在您的服务器上。 按照指南 How To Install and Use PostgreSQL on Ubuntu 20.04 在 Ubuntu 上安装 PostgreSQL。
- PostgreSQL编写查询的基础知识,详见An Introduction to Queries in PostgreSQL。
- 有关如何编写 Node.js 程序的基础知识,请参阅 如何在 Node.js 中编写和运行您的第一个程序。
- 基本了解如何在 JavaScript 中编写异步函数。 通读我们的 Understanding the Event Loop, Callbacks, Promises, and Async/Await in JavaScript 教程来学习基础知识。
第 1 步 - 设置项目目录
在此步骤中,您将为节点应用程序创建目录并使用 npm
安装 node-postgres
。 该目录是您构建 PostgreSQL 数据库和配置文件以进行交互的地方。
使用 mkdir
命令为您的项目创建目录:
mkdir node_pg_app
使用 cd
命令导航到新创建的目录:
cd node_pg_app
使用 npm init
命令用 package.json
文件初始化目录:
npm init -y
-y
标志创建一个默认的 package.json
文件。
接下来,用 npm install
安装 node-postgres
模块:
npm install pg
您现在已经为您的项目设置了目录并安装了 node-postgres
作为依赖项。 您现在已准备好在 Postgres 中创建用户和数据库。
第 2 步 — 在 PostgreSQL 中创建数据库用户和数据库
在这一步中,您将为您的应用程序创建一个数据库用户和数据库。
当您第一次在 Ubuntu 上安装 Postgres 时,它会在您的系统上创建一个用户 postgres
、一个名为 postgres
的数据库用户和一个数据库 postgres
。 用户 postgres
允许您打开 PostgreSQL 会话,您可以在其中执行管理任务,例如创建用户和数据库。
PostgreSQL 使用 ident authentication 连接方案,只要用户名与 Postgres 用户相似,Ubuntu 上的用户就可以登录到 Postgres shell。 由于您已经在 Ubuntu 上拥有一个 postgres
用户,并且在 PostgreSQL 中代表您创建了一个 postgres
用户,因此您将能够登录 Postgres shell。
要登录,请使用 sudo
将 Ubuntu 用户切换到 postgres
并使用 psql
命令登录 Postgres shell:
sudo -u postgres psql
该命令的参数表示:
-u
:在 Ubuntu 上将用户切换到给定用户的标志。 将postgres
用户作为参数传递会将 Ubuntu 上的用户切换到postgres
。psql
:一个 Postgres 交互式终端程序,您可以在其中输入 SQL 命令来创建数据库、角色、表等。
登录 Postgres shell 后,您的终端将如下所示:
postgres
是您将与之交互的数据库的名称,#
表示您以超级用户身份登录。
对于 Node 应用程序,您将创建一个单独的用户和数据库,应用程序将使用该用户和数据库连接到 Postgres。
为此,请使用强密码创建一个新角色:
CREATE USER fish_user WITH PASSWORD 'password';
Postgres 中的角色可以被视为用户或组,具体取决于您的用例。 在本教程中,您将以用户身份使用它。
接下来,创建一个数据库并将所有权分配给您创建的用户:
CREATE DATABASE fish OWNER fish_user;
将数据库所有权分配给 fish_user
将授予角色权限以在 fish
数据库中的表中创建、删除和插入数据。
创建用户和数据库后,退出 Postgres 交互式 shell:
\q
要以 fish_user
身份登录 Postgres shell,您需要在 Ubuntu 上创建一个名称类似于您创建的 Postgres 用户的用户。
使用 adduser
命令创建用户:
sudo adduser fish_user
您现在已经在 Ubuntu 上创建了一个用户、一个 PostgreSQL 用户和一个用于 Node 应用程序的数据库。 接下来,您将使用 fish_user
登录到 PostgreSQL 交互式 shell 并创建一个表。
第 3 步 — 打开一个带有角色的 Postgres Shell 并创建一个表
在本节中,您将使用您在上一节中创建的用户在 Ubuntu 上打开 Postgres shell。 登录到 shell 后,您将为 Node.js 应用程序创建一个表。
要以 fish_user
的身份打开 shell,请输入以下命令:
sudo -u fish_user psql -d fish
sudo -u fish_user
将您的 Ubuntu 用户切换到 fish_user
,然后以该用户身份运行 psql
命令。 -d
标志指定要连接的数据库,在本例中为 fish
。 如果不指定数据库,psql
默认会尝试连接fish_user
数据库,找不到会报错。
登录 psql
shell 后,您的 shell 提示符将如下所示:
fish
表示您现在已连接到 fish
数据库。
您可以使用 \conninfo
命令验证连接:
\conninfo
您将收到类似于以下内容的输出:
OutputYou are connected to database "fish" as user "fish_user" via socket in "/var/run/postgresql" at port "5432".
输出确认您确实以 fish_user
身份登录并且您已连接到 fish
数据库。
接下来,您将创建一个包含应用程序将插入的数据的表。
您将创建的表将跟踪鲨鱼名称及其颜色。 填充数据后,它将如下所示:
ID | 姓名 | 颜色 |
---|---|---|
1 | 萨米 | 蓝色的 |
2 | 何塞 | 青色 |
使用 SQL create table
命令,创建一个表:
CREATE TABLE shark( id SERIAL PRIMARY KEY, name VARCHAR(50) NOT NULL, color VARCHAR(50) NOT NULL);
CREATE TABLE shark
命令创建一个包含 3 列的表:
id
:表的自增字段和主键。 每次插入一行时,Postgres 都会递增并填充id
值。name
和color
:可存储50个字符的字段。NOT NULL
是防止字段为空的约束。
验证表是否已使用正确的所有者创建:
\dt
\dt
命令列出数据库中的所有表。
运行该命令时,输出将类似于以下内容:
List of relations Schema | Name | Type | Owner --------+-------+-------+----------- public | shark | table | fish_user (1 row)
输出确认 fish_user
拥有 shark
表。
现在退出 Postgres shell:
\q
它将带您回到项目目录。
创建表后,您将使用 node-postgres
模块连接到 Postgres。
第 4 步 — 连接到 Postgres 数据库
在这一步中,您将使用 node-postgres
将 Node.js 应用程序连接到 PostgreSQL 数据库。 为此,您将使用 node-postgres
创建一个 连接池 。 连接池用作数据库连接的缓存,允许您的应用程序为所有数据库请求重用连接。 这可以加快您的应用程序并节省您的服务器资源。
在您喜欢的编辑器中创建并打开一个 db.js
文件。 在本教程中,您将使用 nano
,一个终端文本编辑器:
nano db.js
在您的 db.js
文件中,需要在 node-postgres
模块中并使用 解构赋值 从 node-postgres
中提取类 Pool
。
node_pg_app/db.js
const { Pool } = require('pg')
接下来,创建一个 Pool
实例来创建连接池:
node_pg_app/db.js
const { Pool} = require('pg') const pool = new Pool({ user: 'fish_user', database: 'fish', password: 'password', port: 5432, host: 'localhost', })
创建 Pool
实例时,您将配置对象作为参数传递。 此对象包含 node-postgres
将用于建立与 Postgres 的连接的详细信息。
该对象定义了以下属性:
user
:你在 Postgres 中创建的用户。database
:您在 Postgres 中创建的数据库的名称。password
:用户fish_user
的密码。port
:Postgres 正在监听的端口。5432
是默认端口。host
:你希望node-postgres
连接的 Postgres 服务器。 传递它localhost
会将node-postgres
连接到安装在您系统上的 Postgres 服务器。 如果您的 Postgres 服务器驻留在另一个 droplet 上,您的host
将如下所示:host: server_ip_address
。
注意:在生产中,建议将配置值保存在不同的文件中,例如.env
文件。 如果使用 Git 以避免使用版本控制跟踪它,则此文件随后会添加到 .gitignore
文件中。 优点是它可以隐藏敏感信息,例如攻击者的 password
、user
和 database
。
创建实例后,将建立数据库连接,并且 Pool
对象存储在 pool
变量中。 要在您的应用程序中的任何位置使用它,您需要将其导出。 在您的 db.js
文件中,要求并定义 Pool
对象的实例,并设置其属性和值:
node_pg_app/db.js
const { Pool } = require("pg"); const pool = new Pool({ user: "fish_user", database: "fish", password: "password", port: 5432, host: "localhost", }); module.exports = { pool };
保存文件并按 CTRL+X
退出 nano
。 输入 y
保存更改,并在 Mac 上按 ENTER
或 RETURN
键确认您的文件名。
现在您已将应用程序连接到 Postgres,您将使用此连接在 Postgres 中插入数据。
第 5 步 — 将数据插入 Postgres 数据库
在这一步中,您将创建一个程序,该程序使用您在 db.js
文件中创建的连接池将数据添加到 PostgreSQL 数据库中。 为确保程序每次运行时插入不同的数据,您将为其提供接受命令行参数的功能。 运行程序时,您将向其传递鲨鱼的名称和颜色。
在编辑器中创建并打开 insertData.js
文件:
nano insertData.js
在您的 insertData.js
文件中,添加以下代码以使脚本处理命令行参数:
node_pg_app/insertData.js
const { pool } = require("./db"); async function insertData() { const [name, color] = process.argv.slice(2); console.log(name, color); } insertData();
首先,您需要 db.js
文件中的 pool
对象。 这允许您的程序使用数据库连接来查询数据库。
接下来,使用 async
关键字将 insertData()
函数声明为异步函数。 这使您可以使用 await
关键字来使数据库请求异步。
在 insertData()
函数中,您使用 process
模块来访问 命令行参数 。 Node.js process.argv
方法返回数组中的所有参数,包括 node
和 insertData.js
参数。
例如,当您在终端上使用 node insertData.js sammy blue
运行脚本时,process.argv
方法将返回一个数组:['node', 'insertData.js', 'sammy', 'blue']
(为简洁起见,对该数组进行了编辑)。
要跳过前两个元素:node
和 insertData.js
,请将 JavaScript 的 slice()
方法附加到 process.argv
方法。 这将返回从索引 2 开始的元素。 然后将这些参数解构为 name
和 color
变量。
保存文件并使用 CTRL+X
退出 nano
。 使用 node
运行文件并将参数 sammy
和 blue
传递给它:
node insertData.js sammy blue
运行命令后,您将看到以下输出:
Outputsammy blue
该函数现在可以从命令行参数访问 name
和鲨鱼 color
。 接下来,您将修改 insertData()
函数以将数据插入到 shark
表中。
再次在文本编辑器中打开 insertData.js
文件并添加突出显示的代码:
node_pg_app/insertData.js
const { pool } = require("./db"); async function insertData() { const [name, color] = process.argv.slice(2); const res = await pool.query( "INSERT INTO shark (name, color) VALUES ($1, $2)", [name, color] ); console.log(`Added a shark with the name ${name}`); } insertData();
现在,insertData()
函数定义了鲨鱼的 name
和 color
。 接下来,它等待来自 node-postgres
的 pool.query
方法,该方法将 SQL 语句 INSERT INTO shark (name, color) ...
作为第一个参数。 SQL 语句将一条记录插入到 shark
表中。 它使用所谓的 参数化查询 。 $1
和 $2
对应于 pool.query()
方法中作为第二个参数提供的数组中的 name
和 color
变量:[ X152X]。 当 Postgres 执行语句时,变量被替换,安全地保护您的应用程序免受 SQL 注入 。 查询执行后,该函数使用 console.log()
记录成功消息。
在运行脚本之前,将代码封装在 insertData()
函数中的 try...catch 块中以处理运行时错误:
node_pg_app/insertData.js
const { pool } = require("./db"); async function insertData() { const [name, color] = process.argv.slice(2); try { const res = await pool.query( "INSERT INTO shark (name, color) VALUES ($1, $2)", [name, color] ); console.log(`Added a shark with the name ${name}`); } catch (error) { console.error(error) } } insertData()
当函数运行时,try
块内的代码执行。 如果成功,该函数将跳过 catch
块并退出。 但是,如果在 try
块内触发错误,则 catch
块将执行并在控制台中记录错误。
您的程序现在可以接受命令行参数并使用它们将记录插入到 shark
表中。
保存并退出您的文本编辑器。 使用 sammy
和 blue
作为命令行参数运行 insertData.js
文件:
node insertData.js sammy blue
您将收到以下输出:
OutputAdded a shark with the name sammy
运行命令在鲨鱼表中插入一条记录,名称为 sammy
,颜色为 blue
。
接下来,使用 jose
和 teal
作为命令行参数再次执行文件:
node insertData.js jose teal
您的输出将类似于以下内容:
OutputAdded a shark with the name jose
这确认您在 shark
表中插入了另一条记录,名称为 jose
,颜色为 teal
。
您现在已经在 shark
表中插入了两条记录。 在下一步中,您将从数据库中检索数据。
第 6 步 — 从 Postgres 数据库中检索数据
在此步骤中,您将使用 node-postgres
检索 shark
表中的所有记录,并将它们记录到控制台中。
在您喜欢的编辑器中创建并打开文件 retrieveData.js
:
nano retrieveData.js
在您的 retrieveData.js
中,添加以下代码以从数据库中检索数据:
node_pg_app/retrieveData.js
const { pool } = require("./db"); async function retrieveData() { try { const res = await pool.query("SELECT * FROM shark"); console.log(res.rows); } catch (error) { console.error(error); } } retrieveData()
retrieveData()
函数读取 shark
表中的所有行并将它们记录在控制台中。 在函数 try
块中,您可以使用 SQL 语句作为参数从 node-postgres
调用 pool.query()
方法。 SQL 语句 SELECT * FROM shark
检索 shark
表中的所有记录。 一旦检索到它们,console.log()
语句就会记录这些行。
如果触发错误,执行将跳到 catch
块,并记录错误。 在最后一行,您调用 retrieveData()
函数。
接下来,保存并关闭您的编辑器。 运行 retrieveData.js
文件:
node retrieveData.js
您将看到与此类似的输出:
Output[ { id: 1, name: 'sammy', color: 'blue' }, { id: 2, name: 'jose', color: 'teal' } ]
node-postgres
在类似 JSON 的对象中返回表行。 这些对象存储在一个数组中。
您现在可以从数据库中检索数据。 您现在将使用 node-postgres
修改表中的数据。
第 7 步 — 修改 Postgres 数据库中的数据
在此步骤中,您将使用 node-postgres
修改 Postgres 数据库中的数据。 这将允许您更改任何 shark
表记录中的数据。
您将创建一个带有两个命令行参数的脚本:id
和 name
。 您将使用 id
值在表格中选择您想要的记录。 name
参数将是您要更改其名称的记录的新值。
创建并打开 modifyData.js
文件:
nano modifyData.js
在您的 modifyData.js
文件中,添加以下代码以修改 shark
表中的一条记录:
node_pg_app/modifyingData.js
const { pool } = require("./db"); async function modifyData() { const [id, name] = process.argv.slice(2); try { const res = await pool.query("UPDATE shark SET name = $1 WHERE id = $2", [ name, id, ]); console.log(`Updated the shark name to ${name}`); } catch (error) { console.error(error); } } modifyData();
首先,您需要 modifyData.js
文件中的 db.js
文件中的 pool
对象。
接下来,定义一个异步函数 modifyData()
来修改 Postgres 中的记录。 在函数内部,您使用解构赋值从命令行参数定义两个变量 id
和 name
。
在 try
块中,通过将 SQL 语句作为第一个参数传递给 node-postgres
来调用 pool.query
方法。 在 UPDATE
SQL 语句中,WHERE
子句选择与 id
值匹配的记录。 选择后,SET name = $1
将名称字段中的值更改为新值。
接下来,console.log
记录一条消息,该消息在记录名称更改后执行。 最后,在最后一行调用 modifyData()
函数。
使用 CTRL+X
保存并退出文件。 使用 2
和 san
作为参数运行 modifyData.js
文件:
node modifyData.js 2 san
您将收到以下输出:
OutputUpdated the shark name to san
要确认记录名称已从 jose
更改为 san
,请运行 retrieveData.js
文件:
node retrieveData.js
您将获得类似于以下内容的输出:
Outputoutput [ { id: 1, name: 'sammy', color: 'blue' }, { id: 2, name: 'san', color: 'teal' } ]
您现在应该看到 ID 为 2
的记录现在有一个新名称 san
替换 jose
。
完成后,您现在已经使用 node-postgres
成功更新了数据库中的一条记录。
结论
在本教程中,您使用 node-postgres
连接和查询 Postgres 数据库。 您首先在 Postgres 中创建了一个用户和数据库。 然后,您创建了一个表,使用 node-postgres
将应用程序连接到 Postgres,并使用 node-postgres
模块在 Postgres 中插入、检索和修改数据。
有关 node-postgres
的更多信息,请访问他们的 文档 。 为了提高您的 Node.js 技能,您可以探索 如何在 Node.js 系列中编码 。