24

I need to write a script with python sqlalchemy that searchs if a database exist, if the database exists it should query the database else create database and tables.

Pseudocode:

   if db exists cursor.execute(sql)
   else
      create db test;
      create tables;
      insert data;
Cœur
  • 34,719
  • 24
  • 185
  • 251
Herb21
  • 315
  • 1
  • 5
  • 12

7 Answers7

24

You can use the sqlalchemy.engine.base.Engine.connect() method, which will raise a OperationalError if the database does not exist.

import sqlalchemy as sqla
from sqlalchemy import create_engine
from sqlalchemy.exc import OperationalError
db = sqla.create_engine(database_uri)
try:
    db.connect()
    db.execute(sql)
except OperationalError:
    # Switch database component of the uri
    default_database_uri = os.path.join(os.path.dirname(
                           str(db.engine.url)), 'mysql')
    db = sqla.create_engine(default_database_uri)
    # Create your missing database/tables/data here
    # ...
Nav
  • 18,257
  • 26
  • 85
  • 127
Damien
  • 1,372
  • 2
  • 14
  • 25
21

An alternate way if you don't mind to import other libs is to use sqlalchemy_utils. Then database_exists does what you expect, which you may pass the sqlalchemy database uri.

if database_exists('sqllite:////tmp/test.db'):
    do_stuff_with_db(db)

http://sqlalchemy-utils.readthedocs.org/en/latest/database_helpers.html

Code-Apprentice
  • 76,639
  • 19
  • 130
  • 241
Adrian Saldanha
  • 211
  • 2
  • 2
4

I don't know what the canonical way is but here's a way to check to see if a database exists by checking against the list of databases.

from sqlalchemy import create_engine

# This engine just used to query for list of databases
mysql_engine = create_engine('mysql://{0}:{1}@{2}:{3}'.format(user, pass, host, port))

# Query for existing databases
existing_databases = mysql_engine.execute("SHOW DATABASES;")
# Results are a list of single item tuples, so unpack each tuple
existing_databases = [d[0] for d in existing_databases]

# Create database if not exists
if database not in existing_databases:
    mysql_engine.execute("CREATE DATABASE {0}".format(database))
    print("Created database {0}".format(database))

# Go ahead and use this engine
db_engine = create_engine('mysql://{0}:{1}@{2}:{3}/{4}'.format(user, pass, host, port, db))

Here's an alternative method if you don't need to know if the database was created or not.

from sqlalchemy import create_engine

# This engine just used to query for list of databases
mysql_engine = create_engine('mysql://{0}:{1}@{2}:{3}'.format(user, pass, host, port))

# Query for existing databases
mysql_engine.execute("CREATE DATABASE IF NOT EXISTS {0} ".format(database))

# Go ahead and use this engine
db_engine = create_engine('mysql://{0}:{1}@{2}:{3}/{4}'.format(user, pass, host, port, db))
Bryant Kou
  • 1,558
  • 1
  • 17
  • 16
3

Create an engine that connects to the database and executes a universal query like SELECT 1;. If it fails, you can create the DB. How to create the new database depends on the DBMS though.

With PostgreSQL you would connect to the postgres database and issue a CREATE DATABASE statement, then connect to the newly created database.

jd.
  • 10,338
  • 3
  • 44
  • 55
  • i have a pool of database already in existance so if i create a universal query it will pick those and not create the one i want. I was hoping that there is an sqlalchemy equivalent to mysql if not exist create database query. – Herb21 Feb 26 '13 at 09:46
  • 1
    By "universal" I mean it works on all SQL databases - I don't know which backend(s) you're using. `create_engine(my_target_dsn).execute('select 1')` won't interfere with your existing pool. – jd. Feb 26 '13 at 09:51
  • my bad i get you i thought of that but it seemed so plain and easy i didnt think it would work. by the way im using python and sqlalchemy – Herb21 Feb 26 '13 at 09:55
1

You can use https://sqlalchemy-utils.readthedocs.io/en/latest/ There's a helper called database_exists()

mazzi
  • 76
  • 1
  • 5
0

If you do decide to go with sqlalchemy_utils, make sure that you apply your connect_args as a querystring. Otherwise those args won't be carried over when the database_exists function recreates the sqlalchemy engine

from sqlalchemy import create_engine
from sqlalchemy_utils import database_exists

connect_args = {'charset': 'utf8'}
connect_args['ssl_cert'] = 'certs/client-cert.pem'
connect_args['ssl_key'] = 'certs/client-key.pem'
connect_args['ssl_ca'] = 'certs/server-ca.pem'

engine = create_engine(os.environ['MYSQL_CONN_URL'] + '/' + os.environ['DB_NAME'] + '?' +  urlencode(connect_args))
print(database_exists(engine.url))
csaroff
  • 53
  • 2
  • 7
0

Install the pip package

pip install sqlalchemy_utils

Check with database_exists

from sqlalchemy import create_engine
from sqlalchemy_utils import database_exists

engine = create_engine('postgresql://postgres@localhost/name')
database_exists(engine.url)
krema
  • 460
  • 5
  • 14