2011-06-28 3 views
54

С SQLAlchemy, двигатель создается следующим образом:Как создать новую базу данных с помощью SQLAlchemy?

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

Доступ engine завершается неудачно, если база данных нет. Можно ли сказать SQLAlchemy о создании новой базы данных, если указанная база данных не существует?

+2

Создать новую базу данных или просто таблицы? Я не сталкивался с множеством ORM, которые фактически создают базы данных. –

+4

Я нашел [это] (http://www.mail-archive.com/[email protected]/msg05520.html) –

+1

Полезно: http://sqlalchemy-utils.readthedocs.org/en/latest/database_helpers .html –

ответ

66

В postgres по умолчанию обычно присутствуют три базы данных. Если вы можете подключиться как суперпользователь (например, роль postgres), вы можете подключиться к базам данных postgres или template1. По умолчанию pg_hba.conf разрешает только пользователю unix с именем postgres использовать роль postgres, поэтому проще всего просто стать этим пользователем. Во всяком случае, создать двигатель, как обычно, с пользователем, который имеет право доступа для создания базы данных:

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

Вы не можете использовать engine.execute() однако, поскольку Postgres не позволяет создавать базы данных внутри транзакций и SQLAlchemy всегда пытается для запуска запросов в транзакции. Чтобы обойти эту проблему, получите основную связь от двигателя:

>>> conn = engine.connect() 

Но связь все равно будет внутри транзакции, поэтому вы должны закончить открытую сделку с commit:

>>> conn.execute("commit") 

И вы можете приступить к созданию базы данных, используя для этого правильную команду PostgreSQL.

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

Это сработало для меня. В качестве побочного примечания, когда я сделал 'conn.execute ('drop database DBWithCaps'),« у меня были проблемы с этим, не распознавая кепки. 'conn.execute ('drop database" DBWithCaps "')' (с кавычками) отлично работает. – KobeJohn

+0

Я знаю, что PostgreSQL ожидает всех сущностей в нижнем регистре, если не указано. Поэтому, если вы создали поле с использованием MyColumn, некоторые БД возьмут его как mycolumn. Другими словами, не уверен, как вы создали свою таблицу, но если она была создана с использованием кавычек, она * будет * чувствительна к регистру, поэтому, когда вы обращаетесь к ней в инструкции SQL, вам понадобятся кавычки. – guyarad

3

Это позволяет избежать ручного управления транзакциями при создании базы данных, предоставляя isolation_level='AUTOCOMMIT' для create_engine функции:

import sqlalchemy 

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

Кроме того, если вы не уверены в том, что база данных не существует, есть способ игнорировать базы данных ошибка при создании из-за существования подавляя sqlalchemy.exc.ProgrammingError исключение:

import contextlib 
import sqlalchemy.exc 

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

Кажется, что вы не можете подключиться к серверу progres без указания базы данных, поэтому вы, вероятно, захотите подключиться к базе данных postgres по умолчанию для выполнения команд создания db, иначе она попытается подключиться к стандартным " user "и жаловаться, если он не существует. – Acorn

Смежные вопросы