Pyodbc 是否将 SQLWarnings 视为错误?
Does Pyodbc treat SQLWarnings as errors?
我正在编写 Python 代码以使用 Pyodbc 连接到 MS SQL 服务器。
到目前为止,一切进展顺利,我设法在数据库上调用了几个存储过程。
我现在可是运行陷入了困境。我正在调用的存储过程正在输出有关空值的 sqlwarnings
Warning: Null value is eliminated by an aggregate or other SET operation. (8153)
虽然这是 could/should 在 SQL 部分中处理的内容,但我现在只想在 Python 级别忽略它。
代码以相当标准的方式调用(我认为),就像这样(暂时不提供最小代码)
conn = None
try:
#Connection is created in another class, but retrieved here. Works ok.
conn = db_conn.connect_to_db()
cur = conn.cursor()
cur.execute(str_sql)
# This is a hack, but I think is unrelated to the issue
# Sorry I haven't found a better way to make pyodbc wait for the SP to finish than this
#
while cur.nextset():
time.sleep(1)
cur.commit()
cur.close()
return True
except db.Error as ex:
log.error(str(ex.args[1]))
raise ConnectionError(ex.args[1])
问题是在SQL警告时引发了 ConnectionError。 pyodbc 可以配置为忽略这个吗?
相关帖子告诉我关闭存储过程中的 ANSI 警告,但我认为这是一个解决方法。
其他帖子有关于导入“'warnings'”和 catchAll() 警告的内容,但已尝试过,但没有奏效。我想因为 pyodbc 将其视为错误,因此警告部分从未达到 Python.
我是不是理解错了什么,或者这不可能?
Python 版本 3.7
Pyodbc 版本 4.0.32
SQL 服务器的 ODBC 驱动程序 17
从 macOS
调用
好的,所以我确实解决了我的问题。
存储过程确实在我的调用中产生了错误。我直接在数据库上测试调用后发现了这个。
所以回答我自己的问题 no pyodbc 不会将警告视为错误。
但是我确实只在错误中看到了 sql 警告(或者至少据我所知)。 THROW 50001, ......
抛出的真正错误是在 pyodbc.Error
.
中看不到的地方
我试图制作一个最小的可重现示例,但没有成功。下面的代码似乎忽略了错误的抛出。我假设我犯了一些错误,不能使用这种 sql 字符串。预期的行为是落在 ERROR 部分,但正确的值是 returned 在 fetchall 中。
import pyodbc
def test_warnings_after_errors():
# Connect to your own MS SQL database
conn = None
cur = conn.cursor()
try:
cur.execute('''
SELECT C1,
MAX(C2) as MaxC2
FROM (VALUES(1,1),
(1,2),
(2,4),
(1, NULL),
(2,4)) as V(C1, C2)
GROUP BY C1
THROW 51000, 'Will we get this error back?', 1;
'''
)
result = cur.fetchall()
print(result)
except pyodbc.Error as error:
print(error.args[1])
print("Executed sql")
如果我删除整个 select 部分,则会按预期抛出错误。代码按照在 Azure Data Studio 中编写的方式针对服务器运行,在这种情况下,它将 return 错误(以及之前关于 null 的警告)。
为了真正消除我的错误,我必须清理数据,但这与此处发布的问题完全无关。
在我的情况下,我可以接受“奇怪的”sql警告,以防出现错误,但它仍然让我感到困惑。
我正在编写 Python 代码以使用 Pyodbc 连接到 MS SQL 服务器。
到目前为止,一切进展顺利,我设法在数据库上调用了几个存储过程。
我现在可是运行陷入了困境。我正在调用的存储过程正在输出有关空值的 sqlwarnings
Warning: Null value is eliminated by an aggregate or other SET operation. (8153)
虽然这是 could/should 在 SQL 部分中处理的内容,但我现在只想在 Python 级别忽略它。
代码以相当标准的方式调用(我认为),就像这样(暂时不提供最小代码)
conn = None
try:
#Connection is created in another class, but retrieved here. Works ok.
conn = db_conn.connect_to_db()
cur = conn.cursor()
cur.execute(str_sql)
# This is a hack, but I think is unrelated to the issue
# Sorry I haven't found a better way to make pyodbc wait for the SP to finish than this
#
while cur.nextset():
time.sleep(1)
cur.commit()
cur.close()
return True
except db.Error as ex:
log.error(str(ex.args[1]))
raise ConnectionError(ex.args[1])
问题是在SQL警告时引发了 ConnectionError。 pyodbc 可以配置为忽略这个吗?
相关帖子告诉我关闭存储过程中的 ANSI 警告,但我认为这是一个解决方法。
其他帖子有关于导入“'warnings'”和 catchAll() 警告的内容,但已尝试过,但没有奏效。我想因为 pyodbc 将其视为错误,因此警告部分从未达到 Python.
我是不是理解错了什么,或者这不可能?
Python 版本 3.7 Pyodbc 版本 4.0.32 SQL 服务器的 ODBC 驱动程序 17 从 macOS
调用好的,所以我确实解决了我的问题。
存储过程确实在我的调用中产生了错误。我直接在数据库上测试调用后发现了这个。
所以回答我自己的问题 no pyodbc 不会将警告视为错误。
但是我确实只在错误中看到了 sql 警告(或者至少据我所知)。 THROW 50001, ......
抛出的真正错误是在 pyodbc.Error
.
我试图制作一个最小的可重现示例,但没有成功。下面的代码似乎忽略了错误的抛出。我假设我犯了一些错误,不能使用这种 sql 字符串。预期的行为是落在 ERROR 部分,但正确的值是 returned 在 fetchall 中。
import pyodbc
def test_warnings_after_errors():
# Connect to your own MS SQL database
conn = None
cur = conn.cursor()
try:
cur.execute('''
SELECT C1,
MAX(C2) as MaxC2
FROM (VALUES(1,1),
(1,2),
(2,4),
(1, NULL),
(2,4)) as V(C1, C2)
GROUP BY C1
THROW 51000, 'Will we get this error back?', 1;
'''
)
result = cur.fetchall()
print(result)
except pyodbc.Error as error:
print(error.args[1])
print("Executed sql")
如果我删除整个 select 部分,则会按预期抛出错误。代码按照在 Azure Data Studio 中编写的方式针对服务器运行,在这种情况下,它将 return 错误(以及之前关于 null 的警告)。
为了真正消除我的错误,我必须清理数据,但这与此处发布的问题完全无关。
在我的情况下,我可以接受“奇怪的”sql警告,以防出现错误,但它仍然让我感到困惑。