0

我有一个容器化的 Postgres 数据库,我正在尝试创建一个函数和一个触发器:一个关于新行插入的简单通知。

这可能看起来很愚蠢,但我无法找到如何编写代码,我应该将它推送到 Postgres 容器的哪里,以及如何以编程方式将代码插入容器中。

我可以看到以下文件结构

Database/Schemas/public/
|---tables
|  |___requests (tablename)
|  |__Triggers
|
|___Functions
 

在使用/docker-entrypoint-initdb.d/文件夹(Dockerfile 中的副本)时,我只(模糊地)找到了一种复制代码的方法。

此注入仅在创建数据库时有效 - 根据 Docker/Postgres 文档。这意味着我必须删除并重新创建数据库。这是错误的,因为我无法对生产数据库进行任何更改。

此外,当我将其他 SQL 命令连接到.sql文件中的 CREATE TABLE 命令时,这些命令的执行顺序会导致错误(未知表...)。

init.sql以编程方式复制到/docker-entrypoint-initdb.d/文件夹中的文件是:

-- init_table.sql
CREATE TABLE IF NOT EXISTS public.requests (
    id serial PRIMARY KEY,
    ...,
);

-- create_function_notify.sql
CREATE OR REPLACE FUNCTION notify_insert() RETURNS trigger AS
$$
   BEGIN
      PERFORM pg_notify('new_notif', row_to_json(NEW)::text);
      RETURN NEW;
   END;
$$ LANGUAGE plpgsql;


-- create_trigger_new_event.sql
CREATE TRIGGER new_event
   AFTER INSERT
   ON public.requests
   FOR EACH ROW
   EXECUTE PROCEDURE notify_insert();

LANGUAGE plpgsql;

我还尝试了一个“sh”版本(dixit PG docs)但没有成功:它在“$$”周围抛出一个错误。

#/bin/sh

set -e

psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
  CREATE OR REPLACE FUNCTION notify_insert() RETURNS trigger AS
$$
  LANGUAGE plpgsql;
EOSQL
4

1 回答 1

0

在此处输入图像描述

Dockerfile 指令COPY ./pg_notify.sql /docker-entrypoint-initdb.d/为容器化 Postgres 数据库设置所需的触发器和通知相关功能(仅在创建时)。

按照Bergi的说法,正确的代码是:


-- pg_notify.sql

CREATE TABLE IF NOT EXISTS public.requests (
    id serial PRIMARY KEY,
    app varchar,
    url varchar,
    ip varchar,
    host varchar,
    req_at VARCHAR,
    d BIGINT
);


CREATE OR REPLACE FUNCTION notify_insert() RETURNS trigger 
LANGUAGE plpgsql
AS $$
   BEGIN
      PERFORM pg_notify('new_notification', row_to_json(NEW)::text);
      RETURN NEW;
   END;
$$;

CREATE TRIGGER new_event
   AFTER INSERT
   ON requests
   FOR EACH ROW
   EXECUTE PROCEDURE notify_insert();
于 2021-05-23T12:57:01.520 回答