使用SQLAlchemy,创建一个Engine对象:
from sqlalchemy import create_engine
engine = create_engine("postgresql://localhost/mydb")
如果engine
(在这种情况下,create_engine
)的参数中指定的数据库不存在,则访问mydb
将失败。如果指定的数据库不存在,是否可以告诉SQLAlchemy创建新数据库?
答案 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
角色)进行连接,则可以连接到postgres
或template1
数据库。默认的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))