9

I am using SQLAlchemy to generate tables in a specific schema in a PostgreSQL database. If the schema does not exist, I want to create it. I know the PostgreSQL query to check for the existence of the schema:

SELECT exists(select schema_name FROM information_schema.schemata WHERE schema_name = 'foo')

but I want to know how I should handle this using SQLAlchemy.

6 Answers 6

6

@javax's answer is almost correct; the following is a little clarification:

q = exists(select([("schema_name")]).select_from("information_schema.schemata")
    .where("schema_name = 'foo'"))
if not session.query(q).scalar():
    session.execute('CREATE SCHEMA foo;')
Sign up to request clarification or add additional context in comments.

1 Comment

If you get some warnings (eg: python 3.6.6 sqlalchemy 1.0) like: Textual column expression 'schema_name' should be explicitly declared with text('schema_name'), or use column('schema_name') for more specificity (this warning may be suppressed after 10 occurrences). To avoid just wrap with text() each string. ie: q = exists(select([(text("schema_name"))]).select_from(text("information_schema.schemata")).where(text("schema_name = 'foo'")))
4

If you want to integrate it with SQLAlchemy you could use reflection but for an easier and quicker solution:

from sqlalchemy.sql import exists, select
exists(select([("schema_name")]).select_from("information_schema.schemata").
       where("schema_name == 'foo'"))

This will return True or False.

Comments

3

I'm using MySQL and this works for me (with sqlalchemy v1.4.1, python 3.9.1):

import sqlalchemy as sa

engine = sa.create_engine("mysql+pymysql://someuser:somepassword@somehost")
inspector = sa.inspect(engine)
myschema = "someschema"
if myschema in inspector.get_schema_names():
    print(f"{myschema} schema exists")

and if you want to create a schema if it doesn't exist:

if myschema not in inspector.get_schema_names():
    engine.execute(sa.schema.CreateSchema(myschema))
    # optional. set the default schema to the new schema:
    engine.dialect.default_schema_name = myschema

Comments

1

I've been using this with Postgres, though was surprised to learn that IF NOT EXISTS is not part of the SQL standard -

engine.execute('CREATE SCHEMA IF NOT EXISTS foo;')

Apparently it's an extension for Postgres and MySQL - https://www.w3resource.com/sql/sql-basic/create-schema.php

Comments

0

This worked for me. Finds if a schema exists using pure SqlAlchemy:

from sqlalchemy import create_engine
from sqlalchemy import event
from sqlalchemy.schema import CreateSchema, DropSchema
...
engine = create_engine(dbstr)
meta = ModelBase()
...
if not engine.dialect.has_schema(engine, schema=schema_name):
    event.listen(meta.metadata, 'before_create', CreateSchema(schema_name))

meta.metadata.reflect(bind=engine, schema=schema_name)
meta.metadata.create_all(engine, checkfirst=True)

Comments

0

SQLAlchemy 2.0 introduced backend-agnostic way to inspect the database state with Inspector object. It has has_schema method to check if schema exists in database.

I usually use this code if I need to create a new schema if it hasn't been yet presented in the database:

from sqlalchemy import create_engine, inspect
from sqlalchemy.schema import CreateSchema

schema = "new_schema"
connectable = create_engine("postgresql+psycopg2://postgres@localhost/postgres")

with connectable.connect() as connection:
    if not inspect(connection).has_schema(schema):
        connection.execute(CreateSchema(schema))
        connection.commit()

Comments

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.