如何检查PostgreSQL公共架构是否存在?

时间:2014-02-14 14:27:33

标签: sql postgresql schema

运行以下查询:

SELECT exists(
              SELECT schema_name 
                FROM information_schema.schemata 
               WHERE schema_name = 'public'
              ) as schema_exists;

即使公共架构存在,我也总是FALSE

我应该如何检查此架构是否存在?

修改

我正在使用PostgreSQL版本8.4

4 个答案:

答案 0 :(得分:2)

由于您用于测试架构存在的数据库角色,我猜您无法看到公共架构。 information_schema.schemata实际上是一个具有以下定义的视图:

 SELECT 
    current_database()::information_schema.sql_identifier AS catalog_name,
    n.nspname::information_schema.sql_identifier AS schema_name,
    u.rolname::information_schema.sql_identifier AS schema_owner, 
    NULL::character varying::information_schema.sql_identifier AS default_character_set_catalog,
    NULL::character varying::information_schema.sql_identifier AS default_character_set_schema,
    NULL::character varying::information_schema.sql_identifier AS default_character_set_name,
    NULL::character varying::information_schema.character_data AS sql_path
   FROM pg_namespace n, pg_authid u
  WHERE n.nspowner = u.oid AND pg_has_role(n.nspowner, 'USAGE'::text);

documentation中也对此进行了描述。

在这种情况下,您可以使用psql - information_schema中的\d+\d+ information_schema.schemata中获取视图的定义。

您应该使用pg_namespace代替information_schema.schemata

答案 1 :(得分:2)

来自information_schema.schemata的信息取决于您所连接的角色,因此通常不是查询发现模式的正确视图。

doc on information_schema.schemata in 9.3说:

  

视图模式包含当前数据库中的所有模式   由当前启用的角色拥有。

然而,从那句话来看,(至少对我来说)并不十分清楚,为什么你看不到public

在一个邮件列表帖子中,汤姆莱恩有一个更进一步的解释:
http://www.postgresql.org/message-id/11650.1357782995@sss.pgh.pa.us

他的结论:

  

事实上,非超级用户不会看到“public”,“pg_catalog”,也不会看到   甚至“information_schema”本身也在这个视图中,这看起来有点儿   愚蠢的。

看起来与此问题中的问题完全一样。

底线:使用pg_namespace代替information_schema.schemata


这在版本9.4中进行了修改,以符合用户的期望。 current doc说:

  

视图模式包含当前数据库中的所有模式   当前用户可以访问(通过作为所有者或拥有   一些特权)。

USAGE对模式的特权现在足以从这个视图中获取它。

答案 2 :(得分:1)

(作为评论的回答)

直接引用pg_namespace表可能是一个不错的解决方法......

SELECT exists(select 1 from pg_namespace where nspname = 'public') as schema_exists;

我不知道确切的区别是什么,但是知道PostgreSQL内部命名空间“后退”模式。

另外,我相信那些系统pg_ *表不是保证在不同版本之间保持一致,但它至少已经存在7.3(http://www.postgresql.org/docs/7.4/static/catalog-pg-namespace.html)并且现在已经存在(9.3) 0.1)。

答案 3 :(得分:0)

你写的那个查询应该有用......试试这个替代方案:

select count(*) > 0 FROM information_schema.schemata WHERE schema_name = 'public';