V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
iyaozhen
V2EX  ›  Python

Python 怎么捕获 MySQLdb.Warning ?

  •  
  •   iyaozhen ·
    iyaozhen · 2015-12-10 23:22:38 +08:00 · 3118 次点击
    这是一个创建于 3270 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Python 初学者,我在写一个基础类,有个导入文件进 MySQL 的方法,导入时不免会有一些 warning ,我想把 warning 捕获。然后返回给上层业务代码。

    xxx.py:247: Warning: Data truncated for column 'cost' at row 2004
      cursor.execute(load_data_sql)
    xxx.py:247: Warning: Row 2004 was truncated; it contained more data than there were input columns
      cursor.execute(load_data_sql)
    xxx.py:247: Warning: Data truncated for column 'cost' at row 3519
      cursor.execute(load_data_sql)
    xxx.py:247: Warning: Row 3519 was truncated; it contained more data than there were input columns
      cursor.execute(load_data_sql)
    xxx.py:247: Warning: Data truncated for column 'cost' at row 5280
      cursor.execute(load_data_sql)
    xxx.py:247: Warning: Row 5280 was truncated; it contained more data than there were input columns
      cursor.execute(load_data_sql)
    xxx.py:247: Warning: Data truncated for column 'cost' at row 7034
      cursor.execute(load_data_sql)
    xxx.py:247: Warning: Row 7034 was truncated; it contained more data than there were input columns
      cursor.execute(load_data_sql)
    xxx.py:247: Warning: Data truncated for column 'cost' at row 8801
      cursor.execute(load_data_sql)
    xxx.py:247: Warning: Row 8801 was truncated; it contained more data than there were input columns
      cursor.execute(load_data_sql)
    ……
    

    我尝试了一下:

    cursor = db.cursor()
    load_data_sql = "LOAD DATA INFILE \'%s\' IGNORE INTO TABLE %s" \
                    % (cleaned_file_path, table)
    # 捕获 warn
    warnings.filterwarnings('error')
    warn = ''
    try:
        cursor.execute(load_data_sql)
        db.commit()
    except MySQLdb.Error as e:
        db.rollback()
        return {
            'status': -1,
            'message': "load data file sql \"%s\" error: %s" % (load_data_sql, e)
        }
    except MySQLdb.Warning as e:
        return {
            'status': -2,
            'message': "load data file sql \"%s\" warning: %s" % (load_data_sql, e)
        }
    else:
        return {
            'status': 0,
            'message': 'success'
        }
    finally:
        db.close()
    

    上层业务会打日志:

    warning: Data truncated for column 'cost' at row 2004
    

    貌似还行,除了忽略的行,其它数据都导入成功了。但总感觉代码有点 hack ( filterwarnings ),而且只能捕获到一条 Warning ,应该会有很多条的。

    第 1 条附言  ·  2015-12-11 01:11:39 +08:00
    好像是 MySQLdb 库的原因,就只抛出一个 warn
    7 条回复    2016-03-04 14:48:30 +08:00
    billgreen1
        1
    billgreen1  
       2015-12-10 23:48:08 +08:00   ❤️ 1
    遇到这种情况,推荐你修改 cost 字段的类型,使之能够处理更大范围的数据,而不是捕获异常。
    billgreen1
        2
    billgreen1  
       2015-12-10 23:49:58 +08:00   ❤️ 1
    如果你想捕获异常,试试用 logging 记录下来,而不是 return ,这样或许能出现多个 warning
    iyaozhen
        3
    iyaozhen  
    OP
       2015-12-10 23:54:29 +08:00
    @billgreen1 嗯,这个我知道。我这个只是基础方法,目的就是暴露这些问题,上层业务好做修改。

    使用 logging 记录好像不行,还是只会捕获到一条,就执行到 finally 那里了。
    pynix
        4
    pynix  
       2015-12-11 05:54:34 +08:00
    没有 warn 开关?
    gkiwi
        5
    gkiwi  
       2015-12-11 09:10:37 +08:00
    楼主后面不是 append 一个截图么,可以直接修改下源码看看能不能达到效果
    iyaozhen
        6
    iyaozhen  
    OP
       2015-12-11 12:08:14 +08:00
    @gkiwi 到时上线不方便修改库的源码。本地是可以的。只能这样了,抛出一条也行。
    toontong
        7
    toontong  
       2016-03-04 14:48:30 +08:00
    sys.stderror
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   941 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 21:29 · PVG 05:29 · LAX 13:29 · JFK 16:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.