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

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

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

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

  1. 获取 postgres; docker run --name my-postgres -e POSTGRES_PASSWORD={MY_PASSWORD} -p 5432:5432 -d --rm postgres:13.0
  2. 启动 psql; docker exec -it -u postgres my-postgres psql
  3. CREATE DATABASE MY_DB
  4. \connect MY_DB
  5. 粘贴以下 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,并且使用你的操作系统包管理器来安装它们可能会更容易。您还可以查看如何(以及何时)使用您的特定数据库库运行数据库迁移,它可以为您执行创建表等操作。

标签: node.js postgresql docker node-postgres


【解决方案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
    

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

    【讨论】:

      猜你喜欢
      • 2012-12-19
      • 2021-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-29
      • 1970-01-01
      相关资源
      最近更新 更多