¿Cómo crear una nueva base de datos usando SQLAlchemy?

Con SQLAlchemy, el motor se crea así:

from sqlalchemy import create_engine engine = create_engine("postgresql://localhost/mydb") 

El acceso al engine falla si la base de datos no está presente. ¿Es posible decirle a SQLAlchemy que cree una nueva base de datos si la base de datos especificada no existe?

En postgres, normalmente hay tres bases de datos presentes de forma predeterminada. Si puede conectarse como superusuario (por ejemplo, el rol de postgres ), entonces puede conectarse a las bases de datos de postgres o template1 . El pg_hba.conf predeterminado permite que solo el usuario de Unix llamado postgres use el rol de postgres , por lo que lo más simple es convertirse en ese usuario. En cualquier caso, cree un motor como de costumbre con un usuario que tiene los permisos para crear una base de datos:

 >>> engine = sqlalchemy.create_engine("postgres://postgres@/postgres") 

Sin embargo, no puede usar engine.execute() , porque postgres no le permite crear bases de datos dentro de transacciones, y sqlalchemy siempre intenta ejecutar consultas en una transacción. Para solucionar esto, obtenga la conexión subyacente del motor:

 >>> conn = engine.connect() 

Pero la conexión todavía estará dentro de una transacción, por lo que debe finalizar la transacción abierta con un commit :

 >>> conn.execute("commit") 

Y luego puede proceder a crear la base de datos utilizando el comando PostgreSQL adecuado para ello.

 >>> conn.execute("create database test") >>> conn.close() 

SQLAlchemy-Utils proporciona tipos de datos personalizados y varias funciones de utilidad para SQLAlchemy. Puedes instalar la versión oficial más reciente usando pip:

 pip install sqlalchemy-utils 

Los ayudantes de base de datos incluyen una función create_database :

 from sqlalchemy import create_engine from sqlalchemy_utils import database_exists, create_database engine = create_engine("postgres://localhost/mydb") if not database_exists(engine.url): create_database(engine.url) print(database_exists(engine.url)) 

Es posible evitar la administración manual de transacciones mientras se crea la base de datos proporcionando a la función create_engine isolation_level='AUTOCOMMIT' :

 import sqlalchemy with sqlalchemy.create_engine( 'postgresql:///postgres', isolation_level='AUTOCOMMIT' ).connect() as connection: connection.execute('CREATE DATABASE my_database') 

Además, si no está seguro de que la base de datos no exista, hay una manera de ignorar el error de creación de la base de datos debido a la existencia mediante la supresión de la excepción sqlalchemy.exc.ProgrammingError :

 import contextlib import sqlalchemy.exc with contextlib.suppress(sqlalchemy.exc.ProgrammingError): # creating database as above