Error handling in Python-MySQL

后端 未结 1 838
感动是毒
感动是毒 2020-12-03 05:52

I am running a little webservice based on python flask, where I want to execute a small MySQL Query. When I get a valid input for my SQL query, everything is working as expe

相关标签:
1条回答
  • 2020-12-03 06:15

    First point: you have too much code in your try/except block. Better to use distinct try/except blocks when you have two statements (or two groups of statements) that may raise different errors:

    try:
        try:
            curs.execute(sql)
            # NB : you won't get an IntegrityError when reading
        except (MySQLdb.Error, MySQLdb.Warning) as e:
            print(e)
            return None
    
        try: 
            user = curs.fetchone()[0]
            return user
        except TypeError as e:
            print(e)
            return None
    
    finally:
        conn.close()
    

    Now do you really have to catch a TypeError here ? If you read at the traceback, you'll notice that your error comes from calling __getitem__() on None (nb : __getitem__() is implementation for the subscript operator []), which means that if you have no matching rows cursor.fetchone() returns None, so you can just test the return of currsor.fetchone():

    try:
        try:
            curs.execute(sql)
            # NB : you won't get an IntegrityError when reading
        except (MySQLdb.Error, MySQLdb.Warning) as e:
            print(e)
            return None
    
        row = curs.fetchone()
        if row:
            return row[0]
        return None
    
    finally:
        conn.close()
    

    Now do you really need to catch MySQL errors here ? Your query is supposed to be well tested and it's only a read operation so it should not crash - so if you have something going wrong here then you obviously have a bigger problem, and you don't want to hide it under the carpet. IOW: either log the exceptions (using the standard logging package and logger.exception()) and re-raise them or more simply let them propagate (and eventually have an higher level component take care of logging unhandled exceptions):

    try:
        curs.execute(sql)
        row = curs.fetchone()
        if row:
            return row[0]
        return None
    
    finally:
        conn.close()
    

    And finally: the way you build your sql query is utterly unsafe. Use sql placeholders instead:

    q = "%s%%" % data["email"].strip() 
    sql = "select userid from oc_preferences where configkey='email' and configvalue like %s"
    cursor.execute(sql, [q,])
    

    Oh and yes: wrt/ the "View function did not return a response" ValueError, it's because, well, your view returns None in many places. A flask view is supposed to return something that can be used as a HTTP response, and None is not a valid option here.

    0 讨论(0)
提交回复
热议问题