简体   繁体   English

如何检查 PostgreSQL 公共模式是否存在?

[英]How to check if PostgreSQL public schema exists?

Running the following query:运行以下查询:

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

I am getting always FALSE , even if the public schema exists.我总是得到FALSE ,即使存在公共模式。

How should i check if this schema exists?我应该如何检查此架构是否存在?

EDIT编辑

I am using PostgreSQL version 8.4我使用的是 PostgreSQL 8.4 版

I guess you can't see public schema because of the database role you are using to test schema existence.我猜你看不到公共模式,因为你用来测试模式存在的数据库角色。 information_schema.schemata is actually a view with the following definition: 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);

This is also described in documentation .这也在文档中进行了描述。

You can get the definition of views in information_schema using \\d+ in psql - \\d+ information_schema.schemata in this case.你可以得到的视图定义information_schema使用\\d+在psql里- \\d+ information_schema.schemata在这种情况下。

You should use pg_namespace instead of information_schema.schemata您应该使用pg_namespace而不是information_schema.schemata

The information from information_schema.schemata depends on the role you're connected with, so it's not really the right view to query to discover schemas in general.来自information_schema.schemata取决于您所连接的角色,因此通常通过查询来发现模式并不是真正正确的视图。

The doc on information_schema.schemata in 9.3 says: 9.3 中关于information_schema.schemata文档说:

The view schemata contains all schemas in the current database that are owned by a currently enabled role.视图模式包含当前数据库中由当前启用的角色拥有的所有模式。

However it's not quite clear (at least to me) from just that sentence, why you can't see public .然而,仅仅从那句话中并不清楚(至少对我而言),为什么你看不到public

In a mailing-list post, Tom Lane has an explanation the goes a bit further:在邮件列表帖子中,Tom Lane 有一个更进一步的解释:
See http://www.postgresql.org/message-id/11650.1357782995@sss.pgh.pa.ushttp://www.postgresql.org/message-id/11650.1357782995@sss.pgh.pa.us

His conclusion:他的结论:

As things stand, a non-superuser won't see "public", "pg_catalog", nor even "information_schema" itself in this view, which seems a tad silly.就目前情况而言,非超级用户不会在此视图中看到“public”、“pg_catalog”,甚至“information_schema”本身,这似乎有点愚蠢。

which looks exactly like the problem in this question.这看起来与这个问题中的问题完全一样。

Bottom line: use pg_namespace instead of information_schema.schemata底线:使用pg_namespace而不是information_schema.schemata


This was amended in version 9.4 to conform to what users expect.这在 9.4 版中进行了修改,以符合用户的期望。 The current doc says: 当前文档说:

The view schemata contains all schemas in the current database that the current user has access to (by way of being the owner or having some privilege).视图模式包含当前用户有权访问的当前数据库中的所有模式(通过成为所有者或具有某些特权)。

USAGE privilege on a schema is now enough to get it from this view.模式上的USAGE特权现在足以从这个视图中获取它。

(Posting as an answer from comments) (作为评论的答案发布)

Referencing the pg_namespace table directly might be a decent workaround...直接引用 pg_namespace 表可能是一个不错的解决方法......

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

I don't know what the exact differences are, but do know that namespaces "back" schemas internally in PostgreSQL.我不知道确切的区别是什么,但知道命名空间在 PostgreSQL 内部“支持”模式。

Also, I believe those system pg_* tables are not guaranteed to stay consistent across versions, but it has been there since at least 7.3 ( http://www.postgresql.org/docs/7.4/static/catalog-pg-namespace.html ) and is there now (9.3.1).另外,我相信这些系统 pg_* 表不能保证在不同版本之间保持一致,但它至少从 7.3 开始就存在( http://www.postgresql.org/docs/7.4/static/catalog-pg-namespace. html )并且现在在那里(9.3.1)。

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM