【问题标题】:trapping a MySql warning捕获 MySql 警告
【发布时间】:2011-01-07 07:38:08
【问题描述】:

在我的 python 脚本中,我想在我的查询中使用 MySql 捕获“数据被截断的列 'xxx'”警告。

我看到一些帖子建议使用下面的代码,但它不起作用。

您知道在使用此代码之前是否必须导入某些特定模块,或者是否应该调用某些选项/标志?

谢谢大家

阿费格

import MySQLdb
try:
    cursor.execute(some_statement)
    # code steps always here: No Warning is trapped
    # by the code below
except MySQLdb.Warning, e:
    # handle warnings, if the cursor you're using raises them
except Warning, e:
    # handle warnings, if the cursor you're using raises them

【问题讨论】:

    标签: python mysql


    【解决方案1】:

    引发 MySQL 警告为错误:

    import warnings, MySQLdb
    warnings.filterwarnings('error', category=MySQLdb.Warning)
    

    要忽略而不是引发错误,请将"error" 替换为"ignore"

    在 try-except 块中处理它们,例如:

    try:
        # a MySQL DB operation that raises a warning
        # for example: a data truncated warning
    except Warning as a_warning:
        # do something here
    

    【讨论】:

      【解决方案2】:

      如果您想诱捕它以忽略它,请参阅 Python 文档中的“临时禁止警告”:

      https://docs.python.org/2/library/warnings.html#temporarily-suppressing-warnings

      import warnings
      
      with warnings.catch_warnings():
          warnings.simplefilter("ignore")
          # Put here your query raising a warning
      

      否则,只需阅读有关 Python 的“警告”模块的文档,如果您想稍后捕获它们,可以将它们转换为异常等...都在这里:https://docs.python.org/2/library/warnings.html

      【讨论】:

        【解决方案3】:

        只是添加到 Thomas Wouters 的回复中,不需要导入警告模块来将它们变成错误。只需使用“-W 错误”(或忽略)作为 Python 的标志运行您的脚本。

        【讨论】:

        • 最完整的答案是这一点以及@Thomas 接受的答案。
        【解决方案4】:

        停止使用 MySQLdb。它具有截断数据并仅发出警告之类的愚蠢行为。请改用oursql

        【讨论】:

        • 我直接在 SQL 中使用 MySQL 进行查询,但仍然得到“警告:截断不正确......”。那么也许我们应该停止使用 MySQL 而使用 PostgreSQL。哦,我多么希望我能!
        【解决方案5】:

        我会先尝试设置sql_mode。您可以在会话级别执行此操作。如果你执行一个:

        SET @@sql_mode:=TRADITIONAL;
        

        (您也可以在服务器级别设置它,但您需要访问服务器才能执行此操作。并且,在会话级别设置仍然会被覆盖,所以底线是,始终在会话中设置它级别,建立连接后立即)

        然后许多通常是警告的事情变成了错误。我不知道这些在 python 级别是如何表现出来的,但明显的优势是更改不会存储在数据库中。见:http://dev.mysql.com/doc/refman/5.1/en/server-sql-mode.html#sqlmode_traditional

        【讨论】:

        • 酷!我不知道所有与 SQL 相关的东西!
        • 这是设置在“连接”级别还是“光标”级别?因为我尝试将其设置为关键字参数sql_mode in the connect function,以及在打开连接后立即执行它,但我仍然只是收到警告。
        • @Hubro 应该是连接级别。有没有试过 SELECT @@sql_mode 看 TRADITIONAL 模式是否生效?返回的值应包括此处列出的所有内容dev.mysql.com/doc/refman/5.7/en/…
        【解决方案6】:

        您是否尝试过使用 MySQL 的 SHOW WARNINGS 命令?

        【讨论】:

        • 嗨 nosklo。谢谢!我需要测试它。因为在我看来,它在 SQL 客户端比在我的 python 脚本上更有用。我会尽快回复您并感谢 AFeG
        【解决方案7】:

        警告就是:警告。他们被报告给(通常)stderr,但没有做任何其他事情。你不能像异常一样捕获它们,因为它们没有被引发。

        但是,您可以使用warnings 模块配置警告做什么,然后关闭它们或将它们变成异常。例如,warnings.filterwarnings('error', category=MySQLdb.Warning)MySQLdb.Warning warnings 转换为异常(在这种情况下,它们将使用您的 try/except 捕获)或 'ignore' 根本不显示它们。您可以(并且可能应该)拥有比类别更细粒度的过滤器。

        【讨论】:

        • 嗨,托马斯。我刚刚完成了对这段代码的测试,它工作得很好。我非常感谢你。我祝你晚上好。埃格
        • 如果您想忽略某些特定类型的警告,请使用 warnings.filterwarnings('ignore', 'Unknown table .*') 之类的内容。
        • 嗨@ThomasWouters,这看起来是合法的......但是你能告诉我们应该在哪里为一个django项目编写这些warnings.filterwarnings()代码吗?您是否建议在我们进行数据库插入的每个 python 脚本中编写它?或者我们可以使用任何项目范围的设置来使其成为 django 应用程序中各种数据库插入的默认行为?
        猜你喜欢
        • 1970-01-01
        • 2018-05-02
        • 2014-12-04
        • 1970-01-01
        • 2015-11-26
        • 1970-01-01
        • 2013-08-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多