postgresql的扩展:pg_net

pg_net使 PostgreSQL 能够在 SQL 中发出异步 HTTP/HTTPS 请求。它不同于[http]扩展,因为它默认是异步的。这使得它在阻塞函数(如触发器)中很有用。

它消除了服务器不断轮询数据库更改的需要,而是允许数据库主动通知外部资源有关重大事件的信息。

1.介绍

PG_NET扩展使 PostgreSQL 能够在 SQL 中发出异步 HTTP/HTTPS 请求。它消除了服务器不断轮询数据库更改的需要,而是允许数据库主动通知外部资源有关重大事件的信息。它与触发器、cron 作业(例如PG_CRON)和程序无缝集成,解锁了无数可能性。值得注意的是,PG_NET为 Supabase 的 Webhook 功能提供支持,突出了其健壮性和可靠性。

PG_NET扩展的常见用例包括:

  • 调用外部 API
  • 与外部资源同步数据
  • 在发生事件(如插入)时调用无服务器函数

但是,需要注意的是,该扩展有一些限制。目前,它仅支持三种类型的异步请求:

  • 异步 http GET 请求
  • 具有 JSON 有效负载的异步 http POST 请求
  • 异步 http DELETE 请求

不过,最终,PG_NET为开发人员提供了更大的灵活性,使他们能够监控数据库并将其与外部资源连接起来。

1.1.技术说明

该扩展引入了一个新架构,其中包含两个未记录的表,这是 PostgreSQL 中的一种表,它以牺牲持久性为代价来提供性能改进。您可以在此处阅读有关未记录表的更多信息。这两个表是:net

  1. http_request_queue:此表用作等待执行的请求的队列。成功执行请求后,相应的数据将从队列中删除。

    用于创建此表的 SQL 语句为:

    CREATE UNLOGGED TABLE
        net.http_request_queue (
            id bigint NOT NULL DEFAULT nextval('net.http_request_queue_id_seq'::regclass),
            method text NOT NULL,
            url text NOT NULL,
            headers jsonb NOT NULL,
            body bytea NULL,
            timeout_milliseconds integer NOT NULL
        )
    
  2. _http_response:此表包含每个已执行请求的响应。

    用于创建此表的 SQL 语句为:

    CREATE UNLOGGED TABLE
        net._http_response (
            id bigint NULL,
            status_code integer NULL,
            content_type text NULL,
            headers jsonb NULL,
            content text NULL,
            timed_out boolean NULL,
            error_msg text NULL,
            created timestamp with time zone NOT NULL DEFAULT now()
        )
    

当调用三个请求函数 (, , ) 中的任何一个时,它们都会在表中创建一个条目。http_get``http_post``http_delete``net.http_request_queue

2.安装和使用

2.1. 安装

下载资源:Releases · supabase/pg_net (github.com)

![[pg_net安装资源.png]]

make && make install

要使扩展可用于数据库,请添加:postgresql.conf

shared_preload_libraries = 'pg_net'

在 PostgreSQL 中安装

要在 PostgreSQL 中激活扩展,请运行 create extension 命令。该扩展创建自己的名为 net 的架构,以避免命名冲突。

create extension pg_net;

2.2.配置

该扩展创建 3 个可配置变量:

  1. pg_net.batch_size_(默认值:200):_一个整数,用于限制扩展在每次读取期间从 net.http_request_queue 处理的最大行数
  2. pg_net.ttl_(默认值:6 小时):定义net.http_response_中行在被删除之前的最长时间间隔
  3. pg_net.database_name(默认值:‘postgres’):定义扩展应用于哪个数据库的字符串

可以使用以下命令查看所有这些变量:

show pg_net.batch_size;
show pg_net.ttl;
show pg_net.database_name;

您可以通过编辑文件(使用 )或使用以下命令来更改这些内容:postgresql.conf``SHOW config_file;``ALTER SYSTEM

alter system set pg_net.ttl to '1 hour'
alter system set pg_net.batch_size to 500;

然后,重新加载设置并使用以下命令重新启动后台辅助角色:pg_net

select net.worker_restart();

请注意,这样做需要 SUPERUSER,但在 PostgreSQL >= 15 上,您可以执行以下操作:ALTER SYSTEM

grant alter system on parameter pg_net.ttl to ;
grant alter system on parameter pg_net.batch_size to ;

允许普通用户更新设置。pg_net

2.3.使用API说明

2.3.1.GET请求

2.3.1.1. net.http_get函数签名
net.http_get(
    -- url for the request
    url text,
    -- key/value pairs to be url encoded and appended to the `url`
    params jsonb default '{}'::jsonb,
    -- key/values to be included in request headers
    headers jsonb default '{}'::jsonb,
    -- the maximum number of milliseconds the request may take before being cancelled
    timeout_milliseconds int default 1000
)
    -- request_id reference
    returns bigint

    strict
    volatile
    parallel safe
    language plpgsql
2.3.1.2. 函数具体使用
  • 调用API
SELECT net.http_get (
    'https://postman-echo.com/get?foo1=bar1&foo2=bar2'
) AS request_id;
  • 使用 URL 编码的参数调用 API
SELECT net.http_get(
  'https://postman-echo.com/get',
  -- Equivalent to calling https://postman-echo.com/get?foo1=bar1&foo2=bar2&encoded=%21
  -- The "!" is url-encoded as %21
  '{"foo1": "bar1", "foo2": "bar2", "encoded": "!"}'::JSONB
) AS request_id;
  • 使用 API-KEY 调用 API
SELECT net.http_get(
  'https://postman-echo.com/get?foo1=bar1&foo2=bar2',
   headers := '{"API-KEY-HEADER": ""}'::JSONB
) AS request_id;

2.3.2. POST 请求

2.3.2.1. net.http_post函数签名
net.http_post(
    -- url for the request
    url text,
    -- body of the POST request
    body jsonb default '{}'::jsonb,
    -- key/value pairs to be url encoded and appended to the `url`
    params jsonb default '{}'::jsonb,
    -- key/values to be included in request headers
    headers jsonb default '{"Content-Type": "application/json"}'::jsonb,
    -- the maximum number of milliseconds the request may take before being cancelled
    timeout_milliseconds int default 1000
)
    -- request_id reference
    returns bigint

    volatile
    parallel safe
    language plpgsql
2.3.2.2.函数具体使用
  • 向 API 发送数据
SELECT net.http_post(
    'https://postman-echo.com/post',
    '{"key": "value", "key": 5}'::JSONB,
    headers := '{"API-KEY-HEADER": ""}'::JSONB
) AS request_id;
  • 将单个表行作为有效负载发送

注意:如果使用此方法发送多行,则每行将作为单独的请求发送。

WITH selected_row AS (
    SELECT
        *
    FROM target_table
    LIMIT 1
)
SELECT
    net.http_post(
        'https://postman-echo.com/post',
        to_jsonb(selected_row.*),
        headers := '{"API-KEY-HEADER": ""}'::JSONB
    ) AS request_id
FROM selected_row;
  • 将多个表行作为有效负载发送

警告:发送多行时,请注意限制有效负载大小。

WITH selected_rows AS (
    SELECT
        -- Converts all the rows into a JSONB array
        jsonb_agg(to_jsonb(target_table)) AS JSON_payload
    FROM target_table
    -- Generally good practice to LIMIT the max amount of rows
)
SELECT
    net.http_post(
        'https://postman-echo.com/post'::TEXT,
        JSON_payload,
        headers := '{"API-KEY-HEADER": ""}'::JSONB
    ) AS request_id
FROM selected_rows;

2.3.3. DELETE 请求

2.3.3.1. net.http_delete函数签名
net.http_delete(
    -- url for the request
    url text,
    -- key/value pairs to be url encoded and appended to the `url`
    params jsonb default '{}'::jsonb,
    -- key/values to be included in request headers
    headers jsonb default '{}'::jsonb,
    -- the maximum number of milliseconds the request may take before being cancelled
    timeout_milliseconds int default 2000
)
    -- request_id reference
    returns bigint

    strict
    volatile
    parallel safe
    language plpgsql
    security definer
2.3.3.2.函数具体使用

以下示例使用虚拟 Rest API。

  • 向 API 发送删除请求
SELECT net.http_delete(
    'https://dummy.restapiexample.com/api/v1/delete/2'
) AS request_id;
  • 发送将行 ID 作为查询参数的删除请求
WITH selected_id AS (
    SELECT
        id
    FROM target_table
    LIMIT 1 -- if not limited, it will make a delete request for each returned row
)
SELECT
    net.http_delete(
        'https://dummy.restapiexample.com/api/v1/delete/'::TEXT,
        format('{"id": "%s"}', id)::JSONB
    ) AS request_id
FROM selected_id;
  • 发送以行 ID 作为路径参数的删除请求
WITH selected_id AS (
    SELECT
        id
    FROM target_table
    LIMIT 1 -- if not limited, it will make a delete request for each returned row
)
SELECT
    net.http_delete(
        'https://dummy.restapiexample.com/api/v1/delete/' || id
    ) AS request_id
FROM selected_row

你可能感兴趣的:(#,关系型数据库,postgresql,数据库)