Sqlalchemy在USE命令中使用架构名称而不是数据库名称

时间:2019-10-17 18:55:47

标签: python sql-server sqlalchemy pymssql

我正在尝试使用SQLAlchemy通过网络连接到SQL Server数据库。我在使用pyodbc作为驱动程序时遇到了麻烦,因此切换到pymssql,最后设法使用我的用户名“ salas \ guilherme.santo”在“ fit_alunos”数据库中创建引擎并连接到服务器:

from sqlalchemy import create_engine, inspect

eng = create_engine('mssql+pymssql://salas\guilherme.santo:pass@server/fit_alunos?charset=utf8')

然后如果我检查引擎,一切似乎都很好:

insp = inspect(engine)

insp.default_schema_name  # 'SALAS\\Guilherme.Santo'
insp.get_schema_names()  # a list of schemas with the pattern SALAS\\'something'
insp.get_table_names()  # all the tables in my schema, with no problem

但是如果我尝试创建一个MetaData对象并反映引擎:

from sqlachemy import MetaData

meta = MetaData()
meta.reflect(bind=eng)

我得到了这个OperationalError

OperationalError: (pymssql.OperationalError) (911, b"Database 'SALAS\\Guilherme' does not exist. Make sure that the name is entered correctly.DB-Lib error message 20018, severity 16:\nGeneral SQL Server error: Check messages from the SQL Server\n")
[SQL: use [SALAS\Guilherme]]
(Background on this error at: http://sqlalche.me/e/e3q8)

我猜想SQLAlchemy正在解释数据库是“ SALAS \ Guilherme”,架构是“ Santo”,而不是数据库“ fit_alunos”和架构“ SALAS \ Guilherme.Santo”。

有没有一种方法可以配置数据库和模式,以便它可以正确加载?

[编辑]

我在带有echo=True的引擎上运行了反射方法,发现它使用SQL函数获得了数据库名称:

2019-10-17 16:27:16,330 INFO sqlalchemy.engine.base.Engine select db_name()
2019-10-17 16:27:16,330 INFO sqlalchemy.engine.base.Engine {}
2019-10-17 16:27:16,350 INFO sqlalchemy.engine.base.Engine use [SALAS\Guilherme]
2019-10-17 16:27:16,350 INFO sqlalchemy.engine.base.Engine {}
2019-10-17 16:27:16,389 INFO sqlalchemy.engine.base.Engine ROLLBACK
---------------------------------------------------------------------------
MSSQLDatabaseException                    Traceback (most recent call last)

似乎SELECT db_name()返回的是架构名称而不是数据库名称。

然后,我测试了获取数据库名称和模式名称的SQL函数的返回值,这似乎是正确的

with eng.connect() as con: 
     rs = con.execute("select schema_name();") 
     print(rs.fetchall())  # [('SALAS\\Guilherme.Santo',)]
     rs = con.execute("select db_name();") 
     print(rs.fetchall())  # [('fit_alunos',)]

2 个答案:

答案 0 :(得分:2)

这似乎是SQLAlchemy中的错误。我已经打开了一个issue on GitHub,并且在下一版本(1.4)中将包含一个可修复该问题的补丁。

答案 1 :(得分:0)

似乎您需要使用名称并用冒号传递。

pymssql
engine = create_engine('mssql+pymssql://scott:tiger@hostname:port/dbname')