【问题标题】:Calling RESTful Web Services from PostgreSQL procedure/function从 PostgreSQL 过程/函数调用 RESTful Web 服务
【发布时间】:2018-03-14 09:36:43
【问题描述】:

我已经获得了 RESTful Web 服务,可以将数据推送到另一个应用程序的远程数据库中。我需要调用这些服务,通过将 JSON 格式的数据作为 GET/POST 参数发送到 Web 服务来从 PostgreSQL DB 推送数据。是否可以从 PostgreSQL 函数(定期)调用这些 Web 服务,这些函数首先将数据推送到我的数据库中,或者编写 JAVA 代码来调用这些在 PostgreSQL 数据库上运行查询并调用 Web 服务将它们传递给远程数据库。

【问题讨论】:

    标签: postgresql rest web-services


    【解决方案1】:

    使用plpython2u语言:

    解决方案 1:(使用 urllib2)

    CREATE OR REPLACE FUNCTION public.py_pgrest(uri text, body text DEFAULT NULL::text, content_type text DEFAULT 'application/json'::text)
     RETURNS text
     LANGUAGE plpython2u
    AS $function$
        import urllib2
        from urllib2 import Request, urlopen, URLError, HTTPError
        req = Request(uri)
        if body:
            req.add_data(body)
        if content_type:
            req.add_header('Content-Type', content_type)
        try:
            data = urlopen(req)
        except HTTPError as e:
            return e
        except URLError as e:
            if hasattr(e, 'reason'):
                return e.reason
            elif hasattr(e, 'code'):
                return e.code
            else:
                return e
        else:
            return data.read()
    $function$
    ;
    

    解决方案 2:(使用请求)

    CREATE OR REPLACE FUNCTION public.py_pgrest(p_url text, p_method text DEFAULT 'GET'::text, p_data text DEFAULT ''::text, p_headers text DEFAULT '{"Content-Type": "application/json"}'::text)
     RETURNS text
     LANGUAGE plpython2u
    AS $function$
        import requests, json
        try:
            r = requests.request(method=p_method, url=p_url, data=p_data, headers=json.loads(p_headers))
        except Exception as e:
            return e
        else:
            return r.content
    $function$
    ;
    

    【讨论】:

      【解决方案2】:

      解决方案 1: 使用 JOOQ

      首先你从 xml 文件生成类以匹配 postgresql 数据库结构。

      然后您可以在代码中使用它们,例如在您的 Java 应用程序中:

      try (DatabaseContext dbCtx=new DatabaseContext())
          {
      
            DSLContext ctx=dbCtx.getContext();
            ctx.insertInto(TABLE)
            .set(TABLE.ID, values.getId())
            .set(TABLE.DATA, values.getData().toString())
            .execute();
          }
      

      解决方案 2: 使用休眠

      您首先设置 hibernate xml 和 Java 文件来映射您的数据库,类似于 JOOQ 解决方案。

      然后你再次连接到数据库并推送数据。

        Configuration cfg=new Configuration();  
        cfg.configure("your_database_configuration_file.cfg.xml");
        SessionFactory factory=cfg.buildSessionFactory();  
        Session session=factory.openSession();  
        Transaction t=session.beginTransaction();  
      
        TranstateData e1=new TranstateData();  
        e1.setId(idR);  
        e1.setData(dataR);  
        session.persist(e1);
        t.commit();
        session.close(); 
      

      此解决方案比编写 SQL 直接连接到数据库要好,因为您可以在修改表时不时更新(例如,编写一个执行此操作的任务)(这意味着您不必编写配置)两次!代码将自动生成更改)。您还可以更快地发现错误,因为您可以看到您拥有的类和变量。 更不用说它们不是玩 JOOQ 和 Hibernate 的唯一方法……还有其他可能性。互联网上到处都是其他例子。 MyBatis 也是一种解决方案(Solution 3)。所有提到的都支持 PostgreSQL。

      【讨论】:

        【解决方案3】:

        是的,这是可能的,尽管不是直接来自 Postgresql 本身。我不了解 Java,但最快的方法是使用 plperluREST::Client 包,例如:

        CREATE OR REPLACE FUNCTION restful.put(auri character varying, ajson_text text)
         RETURNS text
         LANGUAGE plperlu
         SECURITY DEFINER
        AS $function$
          use REST::Client;  
          use Encode qw(encode);
          my $client = REST::Client->new();    
          $client->getUseragent()->proxy( 'https', 'http://some-proxy/' ); # use for proxy authentication
          $client->addHeader('Content-Type', 'application/json');          # headers
          $client->POST( $_[0], encode('UTF-8', $_[1]));                   # encoding
          return $client->responseContent();  
        $function$
        

        【讨论】:

        • 非常有趣。不幸的是,我在将 plperl 安装到数据库时遇到了麻烦。经过apt-get install postgresql-plperl-10 之后的几次努力并创建了 plperl_call_handler()、plperl_inline_handler(internal) 和 plperl_validator(oid) 我得到了错误:“无法将 REST/Client.pm 加载到 plperl”
        猜你喜欢
        • 1970-01-01
        • 2018-01-21
        • 2014-03-14
        • 2011-08-28
        • 2011-08-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多