【问题标题】:SQLAlchemy Execute with raw SQL containing @DECLARE local tablesSQLAlchemy 使用包含 @DECLARE 本地表的原始 SQL 执行
【发布时间】:2012-02-13 23:58:58
【问题描述】:

我被困住了——我有以下带有 SQL alchemy 的 Python 脚本,我已经非常成功地将其用于其他几个目的。

import sqlalchemy
from sqlalchemy import MetaData
from sqlalchemy.orm import *

engine = sqlalchemy.create_engine("this line of code would provide credentials to the     database")
connection = engine.connect()
session = sessionmaker(bind=engine)
result = connection.execute(sqlquery)

for row in result: print row

虽然最近我发现如果我的“sqlquery”包含 @Declare MyTable 语句,我会收到错误:

"This result object does not return rows. "
sqlalchemy.exc.ResourceClosedError: This result object does not return rows. It has been closed automatically.

这是我的 SQL 查询,它在 SSMS 中运行良好,但当我尝试使用 SQLAlchemy 执行它时不会执行

DECLARE @USER TABLE
(
    UserID INT
    , StatsVals INT
)

INSERT INTO @USER (UserID, StatsVals)
    SELECT TOP 10 u.UserID
    , u.StatsVals
    FROM UserProfile u

SELECT * FROM @USER

有谁知道为什么 SQLAlchemy 会给我这个错误?我应该怎么做才能解决这个问题?

【问题讨论】:

    标签: sql sqlalchemy execute declare


    【解决方案1】:

    当 DBAPI 在游标上执行时,如果结果存在,则需要存在名为 cursor.description 的属性。如果不是,SQLAlchemy 知道没有结果可以返回。

    在这种情况下,这可能是 DBAPI 的问题,除非这种用法属于游标上的“多个结果集”范围。 SQLAlchemy 目前还没有直接支持多个结果集。如果是这种情况,您需要直接使用 DBAPI 游标并调用 .nextset() 来获取结果。您可以通过以下方式获得:

    connection = engine.raw_connection()
    cursor = connection.cursor()
    

    (有关 cursor.nextset() 如何工作的文档,位于 http://www.python.org/dev/peps/pep-0249/

    否则,您真的需要联系 DBAPI 作者,看看您在这里所做的是否真的可行。我猜这是 pyodbc,即使您没有指定您使用的后端。如果是这样,您可以通过http://code.google.com/p/pyodbc/ 与他们联系。

    【讨论】:

      【解决方案2】:

      要更具体地了解 zzzeek 答案,您应该这样做

      from pyodbc import ProgrammingError
      from sqlalchemy import create_engine
      
      # do the connection
      engine = create_engine('mssql+pyodbc://user:password@SERVERNAME/DatabaseName?driver=SQL Server')
      connection = engine.raw_connection()
      cursor = connection.cursor()
      
      # do the query
      cursor.execute(query)
      
      # processing it
      while True:
          try:
              result = cursor.fetchall()
      
              # ... do something with result
      
              if not cursor.nextset(): # trying to get next set
                  break
          except ProgrammingError as ex:
              pass
      

      这有助于我处理具有大量临时表和声明的非常复杂的 MSSQL

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-06-06
        • 2018-09-08
        • 1970-01-01
        • 2015-11-08
        • 2013-08-01
        • 1970-01-01
        • 2011-03-20
        • 2017-03-23
        相关资源
        最近更新 更多