2011-06-28 4 views
54

Con SQLAlchemy, il motore si crea in questo modo:Come creare un nuovo database usando SQLAlchemy?

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

Accesso engine fallisce se il database non è presente. È possibile indicare a SQLAlchemy di creare un nuovo database se il database specificato non esiste?

+2

Creare un nuovo database o solo tabelle? Non ho incontrato molti ORM che in realtà creano database. –

+4

Ho trovato [questo] (http://www.mail-archive.com/[email protected]/msg05520.html) –

+1

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

risposta

66

Su postgres, tre database sono normalmente presenti per impostazione predefinita. Se si è in grado di connettersi come superutente (ad esempio, il ruolo postgres), è possibile connettersi ai database postgres o template1. L'impostazione predefinita pg_hba.conf consente solo all'utente unix denominato postgres di utilizzare il ruolo postgres, quindi la cosa più semplice è diventare quell'utente. In ogni caso, creare un motore come al solito con un utente che dispone delle autorizzazioni per creare un database:

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

Non è possibile utilizzare engine.execute() però, perché Postgres non consente di creare database all'interno di transazioni, e SQLAlchemy cerca sempre per eseguire query in una transazione. Per aggirare il problema, ottenere il collegamento sottostante dal motore:

>>> conn = engine.connect() 

Ma la connessione sarà ancora all'interno di una transazione, in modo da avere per terminare la transazione aperta con un commit:

>>> conn.execute("commit") 

E è quindi possibile procedere alla creazione del database utilizzando il comando PostgreSQL appropriato.

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

Questo ha funzionato bene per me. Come nota a margine, quando ho fatto 'conn.execute ('drop database DBWithCaps')' Ho avuto problemi con esso non riconoscendo i cappucci. 'conn.execute ('drop database' DBWithCaps" ') '(con le virgolette) ha funzionato bene. – KobeJohn

+0

So che PostgreSQL si aspetta che tutte le entità siano in minuscolo, a meno che non siano quotate. Quindi se hai creato un campo usando MyColumn alcuni DB lo prenderanno come mycolumn. In altre parole, non sono sicuro di come hai creato la tua tabella, ma se è stata creata usando le virgolette, * sarà * case-sensitive, quindi quando accederai a una dichiarazione SQL avrai bisogno anche delle virgolette. – guyarad

3

E 'possibile evitare la gestione delle transazioni manuale durante la creazione del database, fornendo isolation_level='AUTOCOMMIT'-create_engine funzione:

import sqlalchemy 

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

anche se non si è certi che database non esiste c'è un modo per ignorare banca dati errore di creazione grazie all'esistenza sopprimendo sqlalchemy.exc.ProgrammingError eccezione:

import contextlib 
import sqlalchemy.exc 

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

Sembra che non sia possibile connettersi a un server progres senza specificare un database, quindi probabilmente vorrai connettersi al database predefinito "postgres" per eseguire i comandi di creazione del db, altrimenti proverà a connettersi al predefinito " utente "e si lamenta se non esiste. – Acorn