如何使用SQLAlchemy创建新数据库?

时间:2011-06-28 12:43:50

标签: python sqlalchemy

使用SQLAlchemy,创建一个Engine对象:

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

如果engine(在这种情况下,create_engine)的参数中指定的数据库不存在,则访问mydb将失败。如果指定的数据库不存在,是否可以告诉SQLAlchemy创建新数据库?

5 个答案:

答案 0 :(得分:94)

SQLAlchemy-Utils为SQLAlchemy提供自定义数据类型和各种实用程序函数。您可以使用pip安装最新的正式版:

pip install sqlalchemy-utils

database helpers包含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))

答案 1 :(得分:85)

在postgres上,默认情况下通常会出现三个数据库。如果您能够以超级用户身份(例如,postgres角色)进行连接,则可以连接到postgrestemplate1数据库。默认的pg_hba.conf仅允许名为postgres的unix用户使用postgres角色,因此最简单的方法就是成为该用户。无论如何,像往常一样创建一个具有创建数据库权限的用户的引擎:

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

但是,您不能使用engine.execute(),因为postgres不允许您在事务中创建数据库,而sqlalchemy总是尝试在事务中运行查询。要解决这个问题,请从引擎获取基础连接:

>>> conn = engine.connect()

但是连接仍然在事务中,因此您必须使用commit结束打开的事务:

>>> conn.execute("commit")

然后,您可以使用适当的PostgreSQL命令继续创建数据库。

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

答案 2 :(得分:4)

通过向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

答案 3 :(得分:2)

使用 with 扩展接受的答案会产生:

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

NEW_DB_NAME = 'database_name'

with engine.connect() as conn:
    conn.execute("commit")
    # Do not substitute user-supplied database names here.
    conn.execute(f"CREATE DATABASE {NEW_DB_NAME}")

答案 4 :(得分:0)

请注意,我无法使用database_exists来获得上述建议,因为每当使用database_exists(engine.url):来检查数据库是否存在时,都会出现此错误:

  

InterfaceError('(pyodbc.InterfaceError)(\'28000 \',u \'[28000]   [Microsoft] [SQL Server Native Client 11.0] [SQL Server]登录失败   用户\\'myUser \\'。 (18456)(SQLDriverConnect); [28000]   [Microsoft] [SQL Server本机客户端11.0] [SQL Server]无法打开   登录名请求的数据库“ MY_DATABASE”。登录失败。   (4060); [28000] [Microsoft] [SQL Server本机客户端11.0] [SQL   服务器]用户\\'myUser \\'的登录失败。 (18456); [28000]   [Microsoft] [SQL Server本机客户端11.0] [SQL Server]无法打开   登录名请求的数据库“ MY_DATABASE”。登录失败。   (4060)\')',)

contextlib/suppress也不起作用,并且我没有使用postgres,所以最终我这样做是为了忽略该数据库,如果SQL Server已经存在该异常:

import logging
import sqlalchemy

logging.basicConfig(filename='app.log', format='%(asctime)s-%(levelname)s-%(message)s', level=logging.DEBUG)
engine = create_engine('mssql+pyodbc://myUser:mypwd@localhost:1234/MY_DATABASE?driver=SQL+Server+Native+Client+11.0?trusted_connection=yes', isolation_level = "AUTOCOMMIT")

try: 
    engine.execute('CREATE DATABASE ' + a_database_name)
except Exception as db_exc:
    logging.exception("Exception creating database: " + str(db_exc))