2011-06-28 27 views
54

Con SQLAlchemy, el motor se crea de esta manera:¿Cómo crear una nueva base de datos usando SQLAlchemy?

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

Acceso 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?

+2

¿Crear una nueva base de datos o simplemente tablas? No he encontrado muchos ORM que realmente crean bases de datos. –

+4

Encontré [this] (http://www.mail-archive.com/[email protected]/msg05520.html) –

+1

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

Respuesta

66

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

>>> engine = sqlalchemy.create_engine("postgres://[email protected]/postgres") 

No puede utilizar engine.execute() sin embargo, debido a Postgres no le permiten crear bases de datos dentro de las transacciones, y sqlalchemy siempre trata para ejecutar consultas en una transacción. Para evitar esto, conseguir la conexión subyacente del motor:

>>> conn = engine.connect() 

Pero la conexión todavía estará dentro de una transacción, así que hay que poner fin a la transacción abierta con un commit:

>>> conn.execute("commit") 

Y a continuación, puede proceder a crear la base de datos utilizando el comando PostgreSQL adecuado para ello.

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

Esto funcionó bien para mí. Como nota al margen, cuando hice 'conn.execute ('drop database DBWithCaps')' tuve problemas al no reconocer los topes. 'conn.execute ('drop database' DBWithCaps '')' (con las comillas) funcionó bien. – KobeJohn

+0

Sé que PostgreSQL espera todas las entidades en minúsculas, a menos que se cite. Entonces, si creaste un campo usando MyColumn algunos DB lo tomarán como mycolumn. En otras palabras, no está seguro de cómo creó su tabla, pero si se creó utilizando comillas, * * hará distinción entre mayúsculas y minúsculas, de modo que cuando acceda a ella en una instrucción SQL, también necesitará las comillas. – guyarad

3

Es posible evitar la gestión de transacciones manuales mientras que la creación de bases de datos, proporcionando isolation_level='AUTOCOMMIT' a create_engine función:

import sqlalchemy 

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

Además, si usted no está seguro de que la base de datos no existe hay una manera de hacer caso omiso de la base de datos error de creación debido a la existencia mediante la supresión de sqlalchemy.exc.ProgrammingError excepción:

import contextlib 
import sqlalchemy.exc 

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

Parece que no puede conectarse a un servidor progres sin especificar una base de datos, por lo que es probable que desee conectarse a la base de datos "postgres" predeterminada para ejecutar los comandos de creación db; de lo contrario, intentará conectarse a la predeterminada " usuario "base de datos y se quejan si no existe. – Acorn

Cuestiones relacionadas