Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLAlchemy: "create schema if not exists"

I want to do the "CREATE SCHEMA IF NOT EXISTS" query in SQLAlchemy. Is there a better way than this:

    engine = sqlalchemy.create_engine(connstr)

    schema_name = config.get_config_value('db', 'schema_name')

    #Create schema; if it already exists, skip this
    try:
        engine.execute(CreateSchema(schema_name))
    except sqlalchemy.exc.ProgrammingError:
        pass

I am using Python 3.5.

like image 386
Jan Pisl Avatar asked Jun 19 '18 11:06

Jan Pisl


4 Answers

I had the same question and the answer, which I found, is:

if not engine.dialect.has_schema(engine, schema_name):
    engine.execute(sqlalchemy.schema.CreateSchema(schema_name))

We can also check schema without engine instance, but using connection

conn = engine.connect()
if conn.dialect.has_schema(conn, schema_name):
    ...
like image 194
stardust Avatar answered Oct 16 '22 20:10

stardust


For MS Sql users, there's no has_schema() but this seems to work:

if schemaname not in conn.dialect.get_schema_names(conn):
   conn.execute(schema.CreateSchema(schemaname))
like image 30
Matthew Avatar answered Oct 16 '22 21:10

Matthew


You can use the excellent sqlalchemy_utils package to do just that, in a very neat way.

First, install the package:

pip install sqlalchemy_utils

Then use it like this:

from sqlalchemy_utils.functions import database_exists, create_database

engin_uri = 'postgres://postgres@localhost/name'

if not database_exists(engin_uri):
    create_database(engin_uri)

The example from the official docs has used PostgreSQL and I have personally used it on MySQL 8.

like image 2
pmsoltani Avatar answered Oct 16 '22 21:10

pmsoltani


My preferred way of doing that task:

from sqlalchemy import inspect
<You might need a few more SQLAlchemy imports

def setup_schemas(engine, metadata):
    inspector = inspect(engine)
    all_schemas = inspector.get_schema_names()
    for schema in metadata._schemas:
        if schema not in all_schemas:
            _create_schema(engine, schema)
    
def _create_schema(engine, schema) -> None:
    stmt = text(f"CREATE SCHEMA {schema}")
    with engine.connect() as conn:
        conn.execute(stmt)
        conn.commit()
like image 1
Konstantin Grigorov Avatar answered Oct 16 '22 20:10

Konstantin Grigorov