如何在节点 pg 中设置 postgres 数据库和表

Posted

技术标签:

【中文标题】如何在节点 pg 中设置 postgres 数据库和表【英文标题】:How to setup postgres database and tables in node pg 【发布时间】:2021-03-14 19:42:34 【问题描述】:

我想分享一个Node 存储库,理想情况下它应该可以在通常的yarn install && yarn start 之后使用。

但是pg 无法将SELECT 连接到/从尚不存在的数据库和表中。

这很麻烦,但目前需要这些前面的步骤:

    获取 postgres; docker run --name my-postgres -e POSTGRES_PASSWORD=MY_PASSWORD -p 5432:5432 -d --rm postgres:13.0 启动 psql; docker exec -it -u postgres my-postgres psql CREATE DATABASE MY_DB \connect MY_DB 粘贴以下 SQL 脚本以创建表
CREATE TABLE my_table (
  id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
  field_1 VARCHAR ( 50 ) UNIQUE NOT NULL,
  field_2 INT NOT NULL,
);

由于我已经从 docker 获取 postgres,docker-componse逻辑 解决方案吗? 我对dockerfile不太熟悉,有没有替代的?

在 node 中初始化 postgres 数据库的最佳实践是什么?

yarn start(或yarn setup)上调用脚本是多么糟糕的想法。任何此类脚本的示例都将不胜感激。

【问题讨论】:

你真的应该学习 Dockerfiles 和自定义镜像是如何工作的;没有它,你只是在使用一种非常迂回的方式来运行 PostgreSQL 和 Node,并且使用你的操作系统包管理器来安装它们可能会更容易。您还可以查看如何(以及何时)使用您的特定数据库库运行数据库迁移,它可以为您执行创建表等操作。 【参考方案1】:

首先,我喜欢让开发人员选择他们想要设置环境的方式,尤其是数据库。有些人喜欢直接启动 postgres 服务器,有些人喜欢启动 docker-compose 或简单地启动 docker。

现在假设您无论如何都想设置所有内容。您有多种选择:

启动数据库

使用泊坞窗

如果你想从 docker 初始化所有东西,你可以添加一个入口点来创建数据库。在其中创建一个文件夹init_script 和一个文件:

./init_scripts/init_db.sh

#!/bin/bash

set -e
set -u

function create_user_and_database() 
  local database=$1
  echo "Creating database '$database' with user '$POSTGRES_USER'"
  psql -v ON_ERROR_STOP=1 \
    --username "$POSTGRES_USER" \
    --dbname=postgres <<-EOSQL
    CREATE DATABASE $database;
EOSQL



if [ -n "$POSTGRES_MY_DB" ]; then
  create_user_and_database $POSTGRES_MY_DB
  echo "Database $POSTGRES_MY_DB created"
fi

灵感来自this script,它可以创建多个 postgres 数据库。然后您可以简单地添加其他脚本来创建表。

现在你可以启动 docker 了

docker start my_postgres_container || docker run \
  --name my_postgres_container \
  --volume "$PWD/init_scripts:/docker-entrypoint-initdb.d/" \
  --env POSTGRES_USER=my_user \
  --env POSTGRES_PASSWORD=my_password \
  --env POSTGRES_MY_DB=my_database \
  --publish 5432:5432 \
  --rm \
  postgres:13

一个卷被挂载到文件夹init_scripts/docker-entrypoint-initdb.d/,docker 将查看它以初始化数据库。 这个脚本可以从 npm 或 yarn 执行:

"scripts": 
  "setup_db": "docker start ...."


与某些数据库相反,您 cannot 启动内存中的 postgres。

实例化数据库(postgres 已经在运行)

来自 nodejs 脚本

独立于 postgres 系统,您可以使用脚本从主连接创建新数据库。

function createDatabase() 
  const client = new Client(masterPostgresUri);
  const user = 'my_user';
  const database = 'my_database';
  await client.connect();
  try 
    await client.query(`CREATE USER $user;`);
    await client.query(`CREATE DATABASE $database;`);
    await client.query(`GRANT ALL PRIVILEGES ON DATABASE $database TO $user;`);
   catch (_err) 
    // The database might already exist, you may want to check before
  
  client.end();

要创建表,您可以使用相同的脚本改用新的数据库连接 uri。

这个脚本也可以在设置中启动。

来自迁移工具

有多种工具可以处理设置和迁移。如果您使用例如 ORM Sequelize,那么在迁移脚本中设置所有内容可能是一个不错的选择。 Sequelize migrations


对我来说,没有完美的解决方案,即使你创建了一个命令来启动一个正确配置的 docker,有人可能会说它没有安装 docker,所以你仍然有依赖。因此,我认为让开发人员选择启动 postgres 的最佳解决方案是很棒的。关于表的创建和迁移,我认为一个工具是合适的,因为这是你必须在生产环境中处理的问题,它会在应用程序重启期间处理它。

【讨论】:

【参考方案2】:

脚本

放置配置的正确位置是在启动脚本中。该脚本应该从中运行两个命令来设置服务器(如果不是)并运行它。示例:

// package.json

  "scripts": 
    "start": "yarn run setup && yarn run server",
    "server": "node app.js",
    "setup": "node setup.js"
  

码头工人

如果你想运行像 db 这样的外部有状态服务,那么你需要将它的状态存储在某个地方。 --rm 选项删除机器及其状​​态。因此,为了防止它删除使用 -v 参数,并将您的 PG 数据库从客户机放到主机。对于 postgres,它可能看起来像这样:

docker run --rm -v "$PWD/data/pg:/var/lib/postgresql/data/" -p 5432 postgres 

但正如您所说,最好使用 docker-compose。

Docker 编写

Docker compose 让您可以将多个容器作为一个容器运行。它使用 compose-files 作为单点配置。使用 compose-files,您可以配置应用程序所需的所有软件(db、redis、文件存储等)并链接应用程序数据。它还允许您在容器中运行您的应用程序。这就是使用 Postgres DB 的应用程序的配置方式:

version: "3.8"
services:
  postgre:
    image: postgre
    ## Store persistent postgres data
    volumes:
      - ./data/pg:/var/lib/postgresql/data/
    environment:
      POSTGRES_USERNAME: admin
      POSTGRES_PASSWORD: '********'
  app:
    image: node
    ports:
      - "8080:8080"
    ## Mount current project to guest as /app
    volumes:
      - .:/app
    ## Set PWD to /app
    working_dir: /app
    command: yarn start

因此,您可以使用docker-compose start 运行您的应用,并使用docker-compose stop 命令停止它。

要从节点的应用容器连接到 postgres,请使用 postgre(或您在撰写文件中指定的名称)作为主机名。

提示

如果您的本地 Node.js 版本与容器版本不同,则可能需要将文件从容器安装到 node_modules/ 并将其放到主机系统上。为此运行:

docker run --rm -v "$PWD:/app" -w /app node yarn install

它将正确版本的节点模块安装到主机中。

【讨论】:

以上是关于如何在节点 pg 中设置 postgres 数据库和表的主要内容,如果未能解决你的问题,请参考以下文章

postgres jdbc 客户端证书用户与数据库用户

如何在 Angular 中使用 pg 节点包

如何在 postgres 中设置锁定超时 - Hibernate

如何在postgres中设置日期变量[重复]

在Perl的DBI连接方法中设置keepalive的任何方法

AWS Lambda NodeJS 连接到 RDS Postgres 数据库