Cod*_*orm 2 python sql-server sqlalchemy parameterized-query pymssql
我正在尝试使用 SqlAlchemy(以及 Pymssql 作为提供程序)在 SQL-Server 数据库上执行简单的原始 SQL 查询。
这是我的第一次尝试(使用execute连接方法并以 **kwargs 方式传递参数):
provider = DataProvider().engine
q = "select url from Crawler.CrawlSource where source=@source"
query = text(q)
result = provider.connect().execute(query, source ='mysource')
Run Code Online (Sandbox Code Playgroud)
我以教程中显示的任何方式传递了参数(作为 kwargs 传递并作为 dict 传递),但是它们都不起作用,并且当execute调用方法时抛出异常,表示'Must declare the scalar variable' @source好像没有参数传递给execute方法,似乎是 ORM (或者可能是数据提供程序(在本例中为 pymssql))无法识别传递给的参数execute方法的参数,并且仅将查询(不带参数)传递给数据库引擎(这会导致异常)。
我猜想 MSSQL-Server 提供程序 (Pymssql) 可能存在一些问题,因为 SQL-Server 不是 SqlAlchemy 和 Python 家族中的一等公民,但没有直接线索可能导致此问题。
正如我上面所说,我也尝试了其他方法
这是我的第二次尝试(使用execute连接方法并将参数作为字典传递):
provider = DataProvider().engine
q = "select url from Crawler.CrawlSource where source=@source"
query = text(q)
result = provider.connect().execute(query, {source :'mysource'})
Run Code Online (Sandbox Code Playgroud)
我的第三次尝试(使用execute引擎对象的方法并以 **kwargs 方式传递参数):
provider = DataProvider().engine
q = "select url from Crawler.CrawlSource where source=@source"
query = text(q)
result = provider.execute(query, source ='mysource')
Run Code Online (Sandbox Code Playgroud)
我的第四次尝试(使用execute引擎对象的方法并将参数作为字典传递):
provider = DataProvider().engine
q = "select url from Crawler.CrawlSource where source=@source"
query = text(q)
result = provider.execute(query, {source :'mysource'})
Run Code Online (Sandbox Code Playgroud)
我的第五次尝试(创建会话并使用execute会话方法并将参数作为字典传递):
provider = DataProvider().engine
session = sessionmaker(bind=provider)()
q = "select url from Crawler.CrawlSource where source=@source"
query = text(q)
result = session.execute(query, {source :'mysource'})
Run Code Online (Sandbox Code Playgroud)
我的第六次尝试(创建会话并使用execute会话方法并以 **kwargs 方式传递参数):
provider = DataProvider().engine
session = sessionmaker(bind=provider)()
q = "select url from Crawler.CrawlSource where source=@source"
query = text(q)
result = session.execute(query, source='mysource')
Run Code Online (Sandbox Code Playgroud)
但正如我之前提到的,上述努力均无效,并且所有这些努力都导致了上述相同的异常
任何帮助,将不胜感激
mssql+pymssql 方言似乎支持 "pyformat" paramstyle。这对我有用:
\n\nimport sqlalchemy as sa\n\nengine = sa.create_engine("mssql+pymssql://@localhost:49242/myDb")\n\nsql = "SELECT word FROM vocabulary WHERE language = %(lang)s"\nparams = {\'lang\': \'Greek\'}\nwith engine.begin() as conn:\n result = conn.execute(sql, params).fetchall()\n print(result)\n # [(\'\xce\xb3\xce\xb9\xce\xbf\xcf\x81\xcf\x84\xce\xae\',), (\'\xce\xb7\xce\xbb\xce\xb5\xce\xba\xcf\x84\xcf\x81\xce\xbf\xce\xbd\xce\xb9\xce\xba\xcf\x8c\xcf\x82 \xcf\x85\xcf\x80\xce\xbf\xce\xbb\xce\xbf\xce\xb3\xce\xb9\xcf\x83\xcf\x84\xce\xae\xcf\x82\',)]\nRun Code Online (Sandbox Code Playgroud)\n如果我们使用 SQLAlchemytext对象,我们还可以使用“命名”参数样式:
sql = sa.sql.text("SELECT word FROM vocabulary WHERE language = :lang")\nparams = {\'lang\': \'Greek\'}\nwith engine.begin() as conn:\n result = conn.execute(sql, params).fetchall()\n print(result)\n # [(\'\xce\xb3\xce\xb9\xce\xbf\xcf\x81\xcf\x84\xce\xae\',), (\'\xce\xb7\xce\xbb\xce\xb5\xce\xba\xcf\x84\xcf\x81\xce\xbf\xce\xbd\xce\xb9\xce\xba\xcf\x8c\xcf\x82 \xcf\x85\xcf\x80\xce\xbf\xce\xbb\xce\xbf\xce\xb3\xce\xb9\xcf\x83\xcf\x84\xce\xae\xcf\x82\',)]\nRun Code Online (Sandbox Code Playgroud)\n该text对象允许我们一致地使用“命名”参数样式,而不管 DB-API 层支持的本机参数样式如何(例如,%s对于 pymssql,?对于 pyodbc)。