问题:如何使用SQLAlchemy创建新数据库?
使用SQLAlchemy,将创建一个Engine对象,如下所示:
from sqlalchemy import create_engine
engine = create_engine("postgresql://localhost/mydb")
engine
如果在参数create_engine
(在这种情况下为mydb
)中指定的数据库不存在,则访问将失败。如果指定的数据库不存在,是否可以告诉SQLAlchemy创建一个新数据库?
回答 0
在postgres上,默认情况下通常存在三个数据库。如果您能够以超级用户身份(例如,postgres
角色)进行连接,则可以连接到postgres
或template1
数据库。默认的pg_hba.conf仅允许名为unix的用户postgres
使用该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()
回答 1
SQLAlchemy-Utils为SQLAlchemy提供自定义数据类型和各种实用程序功能。您可以使用pip安装最新的正式版本:
pip install sqlalchemy-utils
该数据库的助手包括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))
回答 2
通过提供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
请注意,我无法获得上述建议,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 Native Client 11.0] [SQL Server]无法打开登录请求的数据库“ MY_DATABASE”。登录失败。(4060); [28000] [Microsoft] [SQL Server Native客户端11.0] [SQL Server]用户\\’myUser \\’的登录失败。(18456); [28000] [Microsoft] [SQL Server Native Client 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))