mac-docker-php容器连接mac中的pgsql数据库失败以及出现table_msg存错误时的解决方法

以php中的thinkphp 5.1为例,php容器连接mac中的pgsql数据库失败时,出现如下错误

复制代码
[7] PDOException in Connection.php line 528
SQLSTATE[08006] [7] could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5432?

解决:以thinkphp 5.1为例,只需把 database.php 中的 hostname 改为 host.docker.internal 即可,然后,thinkphp 就能访问到数据库了。

复制代码
return [
    // 数据库类型
    'type'            => 'pgsql',
    // 服务器地址
    'hostname'        => 'host.docker.internal'
];

如果可以访问后,再出现 table_msg(unknown) 如下错误时

复制代码
SQLSTATE[42883]: Undefined function: 7 ERROR: function table_msg(unknown) does not exist
LINE 1: ...fault as "default",fields_default as "extra" from table_msg(...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.

解决:在数据库中执行如下sql即可(因为 table_msg 函数需要用户自己定义)

sql 复制代码
CREATE OR REPLACE FUNCTION pgsql_type(a_type varchar) RETURNS varchar AS  
$BODY$  
DECLARE  
     v_type varchar;  
BEGIN  
     IF a_type='int8' THEN  
          v_type:='bigint';  
     ELSIF a_type='int4' THEN  
          v_type:='integer';  
     ELSIF a_type='int2' THEN  
          v_type:='smallint';  
     ELSIF a_type='bpchar' THEN  
          v_type:='char';  
     ELSE  
          v_type:=a_type;  
     END IF;  
     RETURN v_type;  
END;  
$BODY$  
LANGUAGE PLPGSQL;  
  
CREATE TYPE "public"."tablestruct" AS (  
  "fields_key_name" varchar(100),  
  "fields_name" VARCHAR(200),  
  "fields_type" VARCHAR(20),  
  "fields_length" BIGINT,  
  "fields_not_null" VARCHAR(10),  
  "fields_default" VARCHAR(500),  
  "fields_comment" VARCHAR(1000)  
);  
  
CREATE OR REPLACE FUNCTION "public"."table_msg" (a_schema_name varchar, a_table_name varchar) RETURNS SETOF "public"."tablestruct" AS  
$body$  
DECLARE  
     v_ret tablestruct;  
     v_oid oid;  
     v_sql varchar;  
     v_rec RECORD;  
     v_key varchar;  
BEGIN  
     SELECT  
           pg_class.oid  INTO v_oid  
     FROM  
           pg_class  
           INNER JOIN pg_namespace ON (pg_class.relnamespace = pg_namespace.oid AND lower(pg_namespace.nspname) = a_schema_name)  
     WHERE  
           pg_class.relname=a_table_name;  
     IF NOT FOUND THEN  
         RETURN;  
     END IF;  
  
     v_sql='  
     SELECT  
           pg_attribute.attname AS fields_name,  
           pg_attribute.attnum AS fields_index,  
           pgsql_type(pg_type.typname::varchar) AS fields_type,  
           pg_attribute.atttypmod-4 as fields_length,  
           CASE WHEN pg_attribute.attnotnull  THEN ''not null''  
           ELSE ''''  
           END AS fields_not_null,  
           pg_attrdef.adsrc AS fields_default,  
           pg_description.description AS fields_comment  
     FROM  
           pg_attribute  
           INNER JOIN pg_class  ON pg_attribute.attrelid = pg_class.oid  
           INNER JOIN pg_type   ON pg_attribute.atttypid = pg_type.oid  
           LEFT OUTER JOIN pg_attrdef ON pg_attrdef.adrelid = pg_class.oid AND pg_attrdef.adnum = pg_attribute.attnum  
           LEFT OUTER JOIN pg_description ON pg_description.objoid = pg_class.oid AND pg_description.objsubid = pg_attribute.attnum  
     WHERE  
           pg_attribute.attnum > 0  
           AND attisdropped <> ''t''  
           AND pg_class.oid = ' || v_oid || '  
     ORDER BY pg_attribute.attnum' ;  
  
     FOR v_rec IN EXECUTE v_sql LOOP  
         v_ret.fields_name=v_rec.fields_name;  
         v_ret.fields_type=v_rec.fields_type;  
         IF v_rec.fields_length > 0 THEN  
            v_ret.fields_length:=v_rec.fields_length;  
         ELSE  
            v_ret.fields_length:=NULL;  
         END IF;  
         v_ret.fields_not_null=v_rec.fields_not_null;  
         v_ret.fields_default=v_rec.fields_default;  
         v_ret.fields_comment=v_rec.fields_comment;  
         SELECT constraint_name INTO v_key FROM information_schema.key_column_usage WHERE table_schema=a_schema_name AND table_name=a_table_name AND column_name=v_rec.fields_name;  
         IF FOUND THEN  
            v_ret.fields_key_name=v_key;  
         ELSE  
            v_ret.fields_key_name='';  
         END IF;  
         RETURN NEXT v_ret;  
     END LOOP;  
     RETURN ;  
END;  
$body$  
LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;  
  
COMMENT ON FUNCTION "public"."table_msg"(a_schema_name varchar, a_table_name varchar)  
IS '获得表信息';  
  
---重载一个函数  
CREATE OR REPLACE FUNCTION "public"."table_msg" (a_table_name varchar) RETURNS SETOF "public"."tablestruct" AS  
$body$  
DECLARE  
    v_ret tablestruct;  
BEGIN  
    FOR v_ret IN SELECT * FROM table_msg('public',a_table_name) LOOP  
        RETURN NEXT v_ret;  
    END LOOP;  
    RETURN;  
END;  
$body$  
LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;  
  
COMMENT ON FUNCTION "public"."table_msg"(a_table_name varchar)  
IS '获得表信息'; 
相关推荐
星霜笔记1 小时前
Docker 部署 MariaDB+phpMyAdmin+Nextcloud 完整教程
运维·数据库·docker·容器·mariadb
hotlinhao2 小时前
php版的FormCreate使用注意事项
php·crmeb
数据知道4 小时前
容器化部署:用Docker封装机器翻译模型与服务详解
docker·容器·机器翻译
鱼鱼说测试8 小时前
Jenkins+Python自动化持续集成详细教程
开发语言·servlet·php
敲上瘾10 小时前
Linux系统cgroups资源精细化控制基础
linux·测试工具·docker·压力测试·cgroups
伊成12 小时前
Docker 部署 Nginx 完整指南
nginx·docker·容器
网硕互联的小客服13 小时前
Apache 如何支持SHTML(SSI)的配置方法
运维·服务器·网络·windows·php
落日漫游13 小时前
K8s核心组件全解析
运维·docker·运维开发
苏琢玉13 小时前
如何让同事自己查数据?写一个零依赖 PHP SQL 查询工具就够了
mysql·php
共享家952715 小时前
linux-数据链路层
linux·网络·macos