【问题标题】:pymysql: one try except can't catch multi-sql errorspymysql:一次尝试,除了无法捕获多 sql 错误
【发布时间】:2017-11-24 03:00:03
【问题描述】:

更新

conn = pymysql.connect(host='localhost',user='user',password='password',db='mydb',charset='utf8')
cur = conn.cursor(pymysql.cursors.DictCursor)
try:
    query = 'select * from test where id = 1;abcd'
    cur.execute(query)
    res = cur.fetchone()
    print(res)
except Exception as e:
    print(e)

try:
    query = 'select * from test where id = 2;'
    cur.execute(query)
    res = cur.fetchone()
    print(res)
except Exception as e:
    print(e)

代码生成结果如下:

{'name': '', 'score': 1.1, 'id': 1}
(1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'abcd' at line 1")

第一行{'name': '', 'score': 1.1, 'id': 1} 来自第一个try...except...; 之前的第一个查询。然后错误消息来自第二个try...except...,但它来自sql查询abcd,这意味着第二个try...except...中的cur.execute(query)产生异常,因为abcdselect * from test where id = 2;不是' t 执行。

那么我怎样才能忽略abcd 并使第二个查询按预期执行呢?


原始问题
我正在用 python 构建一个 Web 服务器。我使用 MySQL 作为数据库,使用 pymysql 作为数据库的接口。

现在我遇到了一个问题:
当某些sql查询因为;而出错时,即使我使用了try...except...,程序也会被阻塞。下面是一个例子:

import pymysql
import pymysql.cursors

conn = pymysql.connect(host='localhost',user='user',password='password',db='mydb',charset='utf8')
cur = conn.cursor(pymysql.cursors.DictCursor)
try:
    query = 'select * from test where id = 1;abcd'  <--- exception!
    cur.execute(query)
    res = cur.fetchone()
    print(res)
except Exception as e:
    print(e)

query = 'select * from test where id = 2;'
cur.execute(query)
res = cur.fetchone()
print(res)

如您所见,第一个query 是非法的,因为;abcd 是一部分。所以会产生错误。但是,try...except... 无法捕获此异常,因为我发现 print(e) 未执行。这是我收到的消息:

{'score': 1.1, 'name': '', 'id': 1}
Traceback (most recent call last):
  File "db_mysql.py", line 23, in <module>
    cur.execute(query)
  File "/usr/local/lib/python3.5/site-packages/pymysql/cursors.py", line 161, in execute
    while self.nextset():
  File "/usr/local/lib/python3.5/site-packages/pymysql/cursors.py", line 103, in nextset
    return self._nextset(False)
  File "/usr/local/lib/python3.5/site-packages/pymysql/cursors.py", line 98, in _nextset
    conn.next_result(unbuffered=unbuffered)
  File "/usr/local/lib/python3.5/site-packages/pymysql/connections.py", line 860, in next_result
    self._affected_rows = self._read_query_result(unbuffered=unbuffered)
  File "/usr/local/lib/python3.5/site-packages/pymysql/connections.py", line 1057, in _read_query_result
    result.read()
  File "/usr/local/lib/python3.5/site-packages/pymysql/connections.py", line 1340, in read
    first_packet = self.connection._read_packet()
  File "/usr/local/lib/python3.5/site-packages/pymysql/connections.py", line 1014, in _read_packet
    packet.check_error()
  File "/usr/local/lib/python3.5/site-packages/pymysql/connections.py", line 393, in check_error
    err.raise_mysql_exception(self._data)
  File "/usr/local/lib/python3.5/site-packages/pymysql/err.py", line 107, in raise_mysql_exception
    raise errorclass(errno, errval)
pymysql.err.ProgrammingError: (1064, "You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for
the right syntax to use near 'abcd' at line 1")

我不明白为什么try...except... 无法捕捉到错误。此外,似乎产生错误的查询是abcd,而不是select * from test where id = 1;abcd。如果我是对的,我认为; 将此查询分为两个查询。

另外,如果我删除;,这意味着第一个查询变为query = 'select * from test where id = 1abcd'try...except... 可能会捕获错误,因此可以按预期执行第二个查询。

所以我的问题是:为什么try...except... 无法捕捉到错误?如何处理所有的 sql 错误,使程序不会被阻塞?

【问题讨论】:

  • File "db_mysql.py", line 23 — 异常似乎来自不同的脚本。
  • @phd 我不明白。 python脚本只是db_mysql.py
  • 那么我怀疑你已经省略了 shebang 行和它之后的几行。并且错误不在 try/except 块内——它是第 23 行的异常,在 try/except 之外。
  • @phd 啊哈哈。你说的对!所以abcd 绑定在第二个cur.execute 上?让我检查一下...
  • @phd 是的,你是对的。所以我在想我是否可以做类似cur.clear() 的事情来清除所有查询。如果不能,我想只有一种方法可以做到:分析查询,如果有;,则多次执行cur.execute...

标签: python mysql sql-server pymysql


【解决方案1】:

所以我的问题是:为什么 try...except... 无法捕捉到错误?什么 我可以做些什么来处理所有的 sql 错误,这样程序就不会 被屏蔽了?

也许有一个好的例外名称?

try:
    …
except pymysql.err.ProgrammingError as except_detail:
        print("pymysql.err.ProgrammingError: «{}»".format(except_detail))

help(pymysql.err)PyMySQL's Github 上查看所有例外情况

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-12
    • 1970-01-01
    • 1970-01-01
    • 2011-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多