92

I need to create, manage and drop schemas on the fly. If I go to create a schema that already exists, I want to (conditionally, via external means) drop and recreate it as specified. How can I check for the existence of said schema on my Postgres 9 server?

Currently, I'm doing this:

select exists (select * from pg_catalog.pg_namespace where nspname = 'schemaname');

but I feel like there's probably another way... is this the "proper" way to query Postgres for the existence of a particular schema?

1
  • 20
    For future visitors: The upcoming Postgres 9.3 will have a create schema if not exists Commented Aug 2, 2013 at 9:26

11 Answers 11

138

The following query will tell you whether a schema exists.

SELECT schema_name FROM information_schema.schemata WHERE schema_name = 'name';
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks, this was an excellent answer. Here's how I extended it to work perfectly for my needs: SELECT exists(select schema_name FROM information_schema.schemata WHERE schema_name = 'foo');
How to check this in c# ? If I use "ExecuteReader" it shows 1 for all queries.
Use ExecuteScalar to get true or false back.
So - even though this is an older posting, I would like to throw in my two cents (as I was utilizing this very same query, but ran into issues). The specific table mentioned above (schemata) only houses schemas in which the user running the query has been granted ownership to the schema in question. Here is the link for documentation. That being said a better solution might be the following: select distinct table_schema from information_schema.tables where table_schema = 'name'
Using single quotes is important! Double quotes didn't work for me. Might be obvious for others, but it wasn't for me :)
|
73

If you are a total purist or you want to gain some milisecs. I recommend you to make use of postgres native system catalog. One can avoid then nested loop which is caused by calling pg_catalog anyway...

SELECT EXISTS(SELECT 1 FROM information_schema.schemata 
              WHERE schema_name = 'name');

querying information_schema

If you querying pg_namespace directly:

SELECT EXISTS(SELECT 1 FROM pg_namespace WHERE nspname = 'name');

Planer's work is much simpler:

enter image description here

So your own solution was the best.

2 Comments

They have literally the same execution time (0.034s). "Some millisecs" is really a stretch here...
even the time is almost the same IMHO it's worthwhile to get much simpler execution tree (especially with so simple approach)
38

Somewhat related and perhaps of interest to others looking for conditional schema creation. I found myself using code like this in some of my creation scripts:

DO $$
BEGIN

    IF NOT EXISTS(
        SELECT schema_name
          FROM information_schema.schemata
          WHERE schema_name = 'pgcrypto'
      )
    THEN
      EXECUTE 'CREATE SCHEMA pgcrypto';
    END IF;

END
$$;

1 Comment

This it the best solution ever! :-)
11

This can be one of the approaches. Drop the schema first and then create it.

IF EXISTS:
Do not throw an error if the schema does not exist. A notice is issued in this case.

So,

DROP SCHEMA IF EXISTS schema_Name
Create SCHEMA schema_Name

3 Comments

Yeah, but say I wanted to have a step between? i.e. Does SchemaXYZ exist? Yes: does it contain X? No: drop and create; Yes: jump out of function
During that time we will have to do the select exists(...).I found a couple of links with the same requirement. They also tell the same. :) postgresql.1045698.n5.nabble.com/… -- PostgreSQL social.msdn.microsoft.com/forums/en-US/transactsql/thread/… --- SQL Server
Seeing if something throws an error to check a simple condition, is a terrible approach, when there are so many ways to check for a schema, as others have noted.
9

If you want to create a schema if it doesn't exist you can just execute:

CREATE SCHEMA IF NOT EXISTS foo

Source: https://www.postgresql.org/docs/current/sql-createschema.html

Comments

3

This is valid for the PostgreSQL that will check if the schema exists and if not then will create it:

CREATE SCHEMA IF NOT EXISTS tenant;

Comments

1

From http://www.postgresql.org/docs/9.1/static/infoschema-schemata.html (emphasis my own):

The view schemata contains all schemas in the current database that are owned by a currently enabled role.

So your original solution/query is more reliable than Peter's, albeit non-standard.

Comments

1

Use

SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_namespace WHERE nspowner <> 1 AND nspname = 'schemaname');

If you check https://www.postgresql.org/docs/current/static/infoschema-schemata.html, you see

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).

This means the query in accepted answer using information_schema.schemata doesn't show schemas that the current user isn't the owner of or doesn't have the USAGE privilege on.

SELECT 1
FROM pg_catalog.pg_namespace
WHERE nspowner <> 1 -- ignore tables made by postgres itself
AND nspname = 'schemaname';

is more complete and will show all existing schemas that postgres didn't make itself regardless of whether or not you have access to the schema.

Comments

1

another way to check Schema Exists?

to_regnamespace ( text ) → regnamespace

Translates a textual schema name to its OID. A similar result is obtained by casting the string to type regnamespace (see Section 8.19); however, this function will return NULL rather than throwing an error if the name is not found.

so you can use:

select to_regnamespace('public') is not null;

Comments

0

This one worked for me (Postgres 9.3):

Select exists (SELECT 1 FROM information_schema.schemata where catalog_name = 'My_BD_with_UpperCase_characters_in_its_Name')

Comments

-1

NONE of those will work if you have objects (tables,sprocs,views) within a particular schema - IT WILL FAIL during DROP...

CREATE & MANAGE is the easy part.. It's the drop that will get you.. Anyways, I couldn't find a suitable answer, so I posted here for others..

SEE LINK HERE: http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/4753d1b8-f547-44c6-b205-aa2dc22606ba/#6eb8238a-305e-40d5-858e-0fbd70454810

2 Comments

This is not accurate for Postgres. Your answer is referring to constraints of TransactSQL, not PostgreSQL.
You can drop a non-empty schema if you add CASCADE: DROP SCHEMA myschema CASCADE;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.