使用SqlAlChemy执行原始查询(针对SQL-Server数据库和Pymssql)时,传递无法识别的参数并引发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')
我以教程中所示的任何方式传递参数(作为kwargs传递和作为dict传递),但它们都不起作用,并且当调用execute
方法时抛出异常,该异常显示'Must declare the scalar variable' @source
好像没有参数传递给execute
方法,看起来ORM(或者可能是数据提供程序(本例中为pymssql))不识别传递给execute
方法的参数,只传递query(
我猜MSSQL-Server提供程序(Pymssql)可能有问题,因为SQL-Server在SqlAlChemy和Python家族中不是一等公民,但没有直接线索导致此问题。
如上所述,我还尝试了其他方法
这是我的第二次尝试(使用execute
连接方法并将参数作为dict传递):
provider = DataProvider().engine
q = "select url from Crawler.CrawlSource where source=@source"
query = text(q)
result = provider.connect().execute(query, {source :'mysource'})
我的第三次尝试(使用Engine对象的execute
方法,以**kwargs方式传递参数):
provider = DataProvider().engine
q = "select url from Crawler.CrawlSource where source=@source"
query = text(q)
result = provider.execute(query, source ='mysource')
我的第四次尝试(使用Engine对象的execute
方法,参数作为dict传递):
provider = DataProvider().engine
q = "select url from Crawler.CrawlSource where source=@source"
query = text(q)
result = provider.execute(query, {source :'mysource'})
我的第五次尝试(创建Session并使用Session的execute
方法,将参数作为dict传递):
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'})
我的第六次尝试(创建Session,使用Session的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')
但正如我前面提到的,上述努力都没有奏效,它们都导致了上面提到的相同异常
如有任何帮助,我们将不胜感激
解决方案
mssql+pymssql方言似乎支持";pyformat";paramstyle。这对我有效:
import sqlalchemy as sa
engine = sa.create_engine("mssql+pymssql://@localhost:49242/myDb")
sql = "SELECT word FROM vocabulary WHERE language = %(lang)s"
params = {'lang': 'Greek'}
with engine.begin() as conn:
result = conn.execute(sql, params).fetchall()
print(result)
# [('γιορτή',), ('ηλεκτρονικός υπολογιστής',)]
如果使用SQLAlChemytext
对象,还可以使用名为";的参数样式:
sql = sa.sql.text("SELECT word FROM vocabulary WHERE language = :lang")
params = {'lang': 'Greek'}
with engine.begin() as conn:
result = conn.execute(sql, params).fetchall()
print(result)
# [('γιορτή',), ('ηλεκτρονικός υπολογιστής',)]
text
对象允许我们一致使用名为";的参数样式,而不考虑DB-API层支持的本机参数样式(例如,%s
用于pymssql,?
用于pyodbc)。
相关文章