Обработка ошибок sql python

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 expected and I get the right value back. However, if the value is not stored in the database I receive a TypeError

    Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1478, in full_dispatch_request
    response = self.make_response(rv)
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1566, in make_response
    raise ValueError('View function did not return a response')
ValueError: View function did not return a response

I tried to tap into error handling myself and use this code for my project, but it seems like this doesn’t work properly.

#!/usr/bin/python

from flask import Flask, request
import MySQLdb

import json

app = Flask(__name__)


@app.route("/get_user", methods=["POST"])
def get_user():
    data = json.loads(request.data)
    email = data["email"]

    sql = "SELECT userid FROM oc_preferences WHERE configkey='email' AND configvalue LIKE '" + email + "%';";

    conn = MySQLdb.connect( host="localhost",
                            user="root",
                            passwd="ubuntu",
                            db="owncloud",
                            port=3306)
    curs = conn.cursor()

    try:
        curs.execute(sql)
        user = curs.fetchone()[0]
        return user
    except MySQLdb.Error, e:
        try:
            print "MySQL Error [%d]: %s" % (e.args[0], e.args[1])
            return None
        except IndexError:
            print "MySQL Error: %s" % str(e)
            return None
    except TypeError, e:
        print(e)
        return None
    except ValueError, e:
        print(e)
        return None
    finally:
        curs.close()
        conn.close()

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000, debug=True)

Basically I just want to return a value, when everything is working properly and I want to return nothing if it isn’t preferably with an error message on my server. How can I use error handling in a proper way?

EDIT Updated current code + error message.

  1. Home
  2. MySQL Connector/Python Tutorial
  3. Exception Handling in Connector/Python

Last updated on July 27, 2020


Error happens all the time when programming, so its better to equip yourself how to deal with them.

Errors and Warnings #

There are two levels of error message severity in MySQL.

  1. Error
  2. Warning

Error #

An Error indicates a problem with query or command which prevented it from being executed.

mysql> select * from earth;
ERROR 1146 (42S02): Table 'world.earth' doesn't exist

Warning #

Warning tells you some thing unexpected has happened that could cause problem down the line, but it is not severe enough to stop the statement from being executed. We can display warnings using SHOW WARNINGS; command. For example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
mysql> 
mysql> CREATE database if not exists world;
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> show warnings;
+-------+------+------------------------------------------------+
| Level | Code | Message                                        |
+-------+------+------------------------------------------------+
| Note  | 1007 | Can't create database 'world'; database exists |
+-------+------+------------------------------------------------+
1 row in set (0.00 sec)

mysql> 
mysql> 
mysql> SELECT 1/0;
+------+
| 1/0  |
+------+
| NULL |
+------+
1 row in set, 1 warning (0.12 sec)

mysql> show warnings;
+---------+------+---------------+
| Level   | Code | Message       |
+---------+------+---------------+
| Warning | 1365 | Division by 0 |
+---------+------+---------------+
1 row in set (0.00 sec)
mysql>

Error Codes #

Errors and warnings in MySQL contains three pieces of information:

mysql> select * from earth;
ERROR 1146 (42S02): Table 'world.earth' doesn't exist
  1. A unique MySQL specific error code (1146) that is not portable to other databases.

  2. A 5 character code (42S02) called SQLSTATE which is used to indicate success or failure of the operation. The SQLSTATE is portable across other databases. It consists of two parts: the first two character represents SQL error class and the next three represents subclass. Each class can belong to one of the following four categories.

    1. Success (class 00)
    2. Warning (class 01)
    3. No Data (class 02)
    4. Exception (all the others 07-HZ)
  3. A textual description of the error.

So why two error codes?

This is because SQLSTATE represents a group of errors. As a result, we can only use it to handle generic errors. If you want to handle some specific error use MySQL-specific error code.

There are hundreds of MySQL-specific error codes. Fortunately, you don’t need to memorize them as the mysql.connector.errorcode module contains all the MySQL-specific error codes.

>>> 
>>> from mysql.connector import errorcode
>>> errorcode.ER_BAD_TABLE_ERROR
1051
>>>

Exceptions Classes #

All the exception classes for dealing with error and warnings are defined in mysql.connector.errors module.

The mysql.connector.errors.Error is the base class for all the other exceptions. We can use it to catch any kind of exception.

Here is an example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import mysql.connector

db = mysql.connector.connect(option_files='my.conf', use_pure=True)

cursor = db.cursor()

sql = """
CREATE TABLE `city` (
  `ID` int(11) AUTO_INCREMENT PRIMARY KEY,
  `Name` char(35) NOT NULL DEFAULT '',
  `CountryCode` char(3) NOT NULL DEFAULT ''  
)
"""

try:
    cursor.execute(sql)
    db.commit()

except mysql.connector.Error as err:
    print(err)
    print("Error Code:", err.errno)
    print("SQLSTATE", err.sqlstate)
    print("Message", err.msg)

cursor.close()
db.close()

Expected Output:

1050 (42S01): Table 'city' already exists
Error Code: 1050
SQLSTATE 42S01
Message Table 'city' already exists

When an exception is thrown you have access to error code, SQLSTATE and error message in the form of errno, sqlstate and msg attributes of the exception object.

The mysql.connector.errors.Error base class is further subclassed into the following three class:

  1. DatabaseError
  2. InterfaceError
  3. PoolError

Let’s discuss them one by one.

  1. DatabaseError: This exception is raised for errors related to the database. It can catch a variety of errors like problem in data processing, error in SQL syntax, MySQL internal problems etc. If a connection is made and a problem arises then DatabaseError will catch it. There are 6 types of DatabaseError:

    1. DataError
    2. InternalError
    3. IntegrityError
    4. OperationalError
    5. NotSupportedError
    6. ProgrammingError

    1. DataError: This error indicates a problem with the data processing, like division by zero, numeric value out of range, invalid type etc.
    2. InternalError: This exception is raised when the database encounters an internal error. For e.g invalid cursor, transaction out of sync etc.
    3. IntegrityError: This exception is raised when the foreign key constraint fails.
    4. OperationalError: This exception is raised for things that are not in control of the programmer. For e.g unexpected disconnect, error in memory allocation etc, transaction failure, selected database not exists.
    5. NotSupportedError: This exception is raised when you invoke method or api that is not supported. For example, calling rollback() on a connection that doesn’t support the transaction.
    6. ProgrammingError: This exception is raised of programming errors. For e.g table not found or already exists, error in MySQL syntax, wrong number of parameters specified, wrong connection credentials etc.
  2. InterfaceError: This exception is raised for errors related to the interface (in our case interface is MySQL Connector/Python) rather than the database itself.

  3. PoolError: It is raised for errors related to connection pooling. We will learn about the connection pooling in the upcoming chapter.

The following figure shows the hierarchy of the exception classes:

StandardError
|__ Error
    |__ InterfaceError
    |__ PoolError
    |__ DatabaseError
        |__ DataError
        |__ InternalError 
        |__ IntegrityError
        |__ OperationalError        
        |__ NotSupportedError
        |__ ProgrammingError

All the exception classes are mapped to one or more SQLSTATE class, you can print this mapping by typing the following command.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
>>>
>>> from mysql.connector import errors
>>> from pprint import pprint
>>> 
>>> pprint(errors._SQLSTATE_CLASS_EXCEPTION)
{'02': <class 'mysql.connector.errors.DataError'>,
 '07': <class 'mysql.connector.errors.DatabaseError'>,
 '08': <class 'mysql.connector.errors.OperationalError'>,
 '0A': <class 'mysql.connector.errors.NotSupportedError'>,
 '0K': <class 'mysql.connector.errors.OperationalError'>,
...
 'HY': <class 'mysql.connector.errors.DatabaseError'>,
 'HZ': <class 'mysql.connector.errors.OperationalError'>,
 'XA': <class 'mysql.connector.errors.IntegrityError'>}
>>> 
>>>

Let’s look at some examples now.

Example 1: Handling the Generic Error

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import mysql.connector

db = mysql.connector.connect(option_files='my.conf', use_pure=True)

cursor = db.cursor()

sql = """
select * from town limit 5
"""

try:
    cursor.execute(sql)

    for row in cursor:
        print(row)


    cursor.close()
    db.close()

except mysql.connector.ProgrammingError as err:
    print(err.errno)
    print(err.sqlstate)
    print(err.msg)

except mysql.connector.Error as err:
    print(err)

Remember that ProgrammingError can catch a variety of exceptions ranging from syntax error to table not found. If you want to catch some specific error use the errorcode module.

Example 2: Handling a specific error

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import mysql.connector
from mysql.connector import errorcode

db = mysql.connector.connect(option_files='my.conf', use_pure=True)

cursor = db.cursor()

sql = """
select * from town limit 5
"""

try:
    cursor.execute(sql)

    for row in cursor:
        print(row)

    db.close()

except mysql.connector.ProgrammingError as err:
    if errorcode.ER_NO_SUCH_TABLE == err.errno:
        print("No table exists")
    else:
        print("Table exists")
        print(err)

except mysql.connector.Error as err:
    print("Some other error")
    print(err)

Example 3: Handling multiple errors in the same way

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import mysql.connector

db = mysql.connector.connect(option_files='my.conf', use_pure=True)

cursor = db.cursor()

sql = """
insert into city(Name, CountryCode, District, Population)
VALUES ('Kabul', 'AFGANISTAN', 'Kabol', 1780000)
"""

try:
    cursor.execute(sql)

    db.commit()
    db.close()

except (mysql.connector.IntegrityError, mysql.connector.DataError) as err:
    print("DataError or IntegrityError")
    print(err)

except mysql.connector.ProgrammingError as err:
    print("Programming Error")
    print(err)

except mysql.connector.Error as err:
    print(err)

Handling Warnings #

By default, MySQL Connector/Python neither fetch warnings nor raise an exception on warnings. But, we can change that using the following arguments of the connect() function.

Argument Description
get_warnings If set to True warnings are fetched automatically after each query without having to manually execute SHOW WARNINGS query. Its default value is False.
raise_on_warnings If set to True, an exception is raised on warnings. It defaults to False. Setting raise_on_warnings=True, also sets get_warnings=True

The above two arguments are also available as properties of the connection object, which can be used to set and retrieve the current setting.

import mysql.connector
from mysql.connector import errors

db = mysql.connector.connect(option_files='my.conf')

db.get_warnings = True  # this is not required if raise_on_warnings=True
db.raise_on_warnings = True

Once you have set get_warnings=True (or raise_on_warnings=True), to retrieve the actual warning use the fetchwarnings() method of the cursor object. The fetchwarnings() method returns a list of tuples containing message-level, error code and the message itself generated by the previously executed query.

The following example demonstrates how to fetch warnings produced by the queries:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import mysql.connector

db = mysql.connector.connect(option_files='my.conf',
                             get_warnings=True)

# db.get_warnings = True  # we could have set get_warnings like this too

cursor = db.cursor()

cursor.execute("CREATE database if not exists world;")
print(cursor.fetchwarnings())

cursor.execute("select 1/0;")
cursor.fetchall() # fetch all the rows from the result set
print(cursor.fetchwarnings())

Expected Output:

[('Note', 1007, "Can't create database 'world'; database exists")]
[('Warning', 1365, 'Division by 0')]

Note that, if the query returns result set (like the SELECT statement) then it is necessary for you to fetch all the rows before calling the fetchwarnings() method, otherwise, the fetchwarnings() method would return None.

Here is an example which shows how to raise exceptions on warnings.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import mysql.connector
from mysql.connector import errors

db = mysql.connector.connect(option_files='my.conf',
                             raise_on_warnings=True)

# db.raise_on_warnings = True  # we could have set raise_on_warnings like this

cursor = db.cursor()

try:

    cursor.execute("CREATE database if not exists world;")
    print(cursor.fetchwarnings())

    cursor.execute("select 1/0;")
    print(cursor.fetchall()) # fetch all the rows from the result set
    print(cursor.fetchwarnings())

except errors.DatabaseError as e:
    print(e)

except:
    print('some error occurred')

Expected Output:

1007: Can't create database 'world'; database exists

Note that setting raise_on_warnings=True implicitly sets get_warnings=True.

You should now have a pretty good idea of how to handle errors in the next few pages we will see some practical examples of SELECT, INSERT, UPDATE and DELTETE statements:



Error handling is a crucial aspect of any programming language, especially when it comes to databases. In Python-MySQL, the way to handle errors depends on the version of the MySQL Connector API that is being used. The API has evolved over time and there are different methods for handling errors in each version. Regardless of the version, it is important to handle errors properly in order to prevent your program from crashing and to ensure that you are able to detect and fix any issues that may arise.

Method 1: Using mysql-connector-python

How to fix Error handling in Python-MySQL using mysql-connector-python

Here are the steps to handle errors in Python-MySQL using mysql-connector-python:

  1. Import the mysql-connector-python module:
  1. Create a connection to the MySQL database:
try:
    cnx = mysql.connector.connect(user='username', password='password',
                              host='hostname',
                              database='database_name')
except mysql.connector.Error as err:
    print("Something went wrong: {}".format(err))
  1. Create a cursor object to execute SQL queries:
try:
    cursor = cnx.cursor()
except mysql.connector.Error as err:
    print("Something went wrong: {}".format(err))
  1. Execute SQL queries using the cursor object:
try:
    cursor.execute(query)
except mysql.connector.Error as err:
    print("Something went wrong: {}".format(err))
  1. Handle exceptions and errors using try-except blocks:
try:
    # execute SQL query
except mysql.connector.Error as err:
    # handle the error
finally:
    # close the cursor and connection
  1. Commit the changes to the database:
try:
    cnx.commit()
except mysql.connector.Error as err:
    print("Something went wrong: {}".format(err))
  1. Close the cursor and connection:
try:
    cursor.close()
    cnx.close()
except mysql.connector.Error as err:
    print("Something went wrong: {}".format(err))

These are the basic steps to handle errors in Python-MySQL using mysql-connector-python. You can customize the error handling based on your specific needs.

Method 2: Using MySQLdb

To handle errors in Python-MySQL using MySQLdb, you can use the try-except block to catch any exceptions that may occur during the database operations. Here is an example code:

import MySQLdb

try:
    conn = MySQLdb.connect(host='localhost', user='user', passwd='password', db='database')
except MySQLdb.Error as e:
    print(f"Error connecting to MySQL database: {e}")
    exit()

try:
    cursor = conn.cursor()
    cursor.execute("SELECT * FROM table")
    results = cursor.fetchall()
except MySQLdb.Error as e:
    print(f"Error executing query: {e}")
    conn.rollback()
    exit()

try:
    conn.commit()
    conn.close()
except MySQLdb.Error as e:
    print(f"Error closing database connection: {e}")

In the code above, we first try to connect to the database using MySQLdb.connect(). If an error occurs, we catch the exception and print an error message.

Next, we execute a query using cursor.execute() and fetch the results using cursor.fetchall(). If an error occurs, we catch the exception, print an error message, and rollback the transaction.

Finally, we commit the changes and close the database connection using conn.commit() and conn.close(). If an error occurs, we catch the exception and print an error message.

By using the try-except block and catching any exceptions that may occur during database operations, we can handle errors in Python-MySQL using MySQLdb.

Method 3: Using PyMySQL

How to Fix Error Handling in Python-MySQL using PyMySQL

Here are the steps to fix error handling in Python-MySQL using PyMySQL:

  1. Import the PyMySQL module:
  1. Connect to the MySQL database using PyMySQL:
try:
    connection = pymysql.connect(host='localhost',
                                 user='username',
                                 password='password',
                                 db='database_name',
                                 charset='utf8mb4',
                                 cursorclass=pymysql.cursors.DictCursor)
except pymysql.Error as e:
    print(f"Error connecting to MySQL database: {e}")
  1. Execute queries using the cursor:
try:
    with connection.cursor() as cursor:
        sql = "SELECT * FROM `table_name`"
        cursor.execute(sql)
        result = cursor.fetchall()
        print(result)
except pymysql.Error as e:
    print(f"Error executing query: {e}")
  1. Commit changes to the database:
try:
    connection.commit()
except pymysql.Error as e:
    print(f"Error committing changes to database: {e}")
  1. Close the database connection:
try:
    connection.close()
except pymysql.Error as e:
    print(f"Error closing database connection: {e}")

By following these steps, you can handle errors in Python-MySQL using PyMySQL.

Introduction

This article will provide a brief overview of how you can better handle PostgreSQL Python exceptions while using the psycopg2 adapter in your code. Make sure that the psycopg2 package is installed on your machine using the PIP3 package manager for Python 3 using the following command:

We’ll also be building a function from scratch that prints detailed information about the psycopg2 exceptions by accessing several of its exception library attributes. It should be noted, however, that this is mostly for educational and debugging purposes, and it should be noted that, in the implementation phase your website or application, you may want to handle them less explicitly.

Catching and handling exceptions in Python

A Python script will terminate as soon as an exception or error is raised, but there is a try-except block (that works in a similar fashion to the try {} catch(err) {} code block in PHP or JavaScript) that will allow you to catch the exception, handle it, and then respond to it with more code within the except: part of the indentation block.

The following code allows you to catch all exceptions, as a wildcard, and print them out without having to explicitly mention the exact exception:

1
2
3
4
5
6

try:
    a = 1234
    print (a + » hello world»)
except Exception as error:
    print («Oops! An exception has occured:», error)
    print («Exception TYPE:», type(error))

the except Exception as error: bit will allow you to handle any exception, and return the exception information as a TypeError class object using Python’s as keyword.

Screenshot of Python IDLE returning exception information in a try-except indentation block

Exception libraries for the psycopg2 Python adapter

Some of the two most commonly occurring exceptions in the psycopg2 library are the OperationalError and ProgrammingError exception classes.

An OperationalError typically occurs when the parameters passed to the connect() method are incorrect, or if the server runs out of memory, or if a piece of datum cannot be found, etc.

A ProgrammingError happens when there is a syntax error in the SQL statement string passed to the psycopg2 execute() method, or if a SQL statement is executed to delete a non-existent table, or an attempt is made to create a table that already exists, and exceptions of that nature.

Complete list of the psycopg2 exception classes

Here’s the complete list of all of psycopg2 exception classes:

InterfaceError, DatabaseError, DataError, OperationalError, IntegrityError, InternalError, ProgrammingError, and NotSupportedError.

Brief overview of PostgreSQL Error Codes

There is an extensive list of over 200 error codes on the postgresql.org website that describes, in detail, each five-character SQL exception.

In the psycopg2 adapter library you can return the code by accessing the exception’s pgcode attribute. It should be an alpha-numeric string, five characters in length, that corresponds to an exception in the PostgreSQL Error Codes table.

Here’s some example code showing how one can access the attribute for the PostgreSQL error code:

1
2
3
4
5

try:
        cursor.execute(«INVALID SQL STATEMENT»)
    except Exception as err:
        print («Oops! An exception has occured:», error)
        print («Exception TYPE:», type(error))

Import the exception libraries for the psycopg2 Python adapter

You’ll need to import the following libraries at the beginning of your Python script:

1
2
3
4
5
6
7
8

# import sys to get more detailed Python exception info
import sys

# import the connect library for psycopg2
from psycopg2 import connect

# import the error handling libraries for psycopg2
from psycopg2 import OperationalError, errorcodes, errors

Get the psycopg2 version string

Older versions of the psycopg2 adapter may handle some exceptions differently. Here’s some code that imports the __version__ attribute string for the psycopg2 library and prints it:

1
2
3
4
5

# import the psycopg2 library’s __version__ string
from psycopg2 import __version__ as psycopg2_version

# print the version string for psycopg2
print («psycopg2 version:», psycopg2_version, «\n«)

Screenshot of Python's IDLE getting the version string for psycopg2

Define a Python function to handle and print psycopg2 SQL exceptions

The code in this section will define a Python function that will take a Python TypeError object class and parse, both the psycopg2 and native Python, exception attributes from it in order to print the details of the exception:

Define the ‘print_psycopg2_exception()’ Python function

Use Python’s def keyword to define a new function and make it accept a TypeError Python object class as its only parameter:

1
2

# define a function that handles and parses psycopg2 exceptions
def print_psycopg2_exception(err):

Use Python’s built-in ‘sys’ library to get more detailed exception information

The next bit of code grabs the traceback information for the exception, including the line number in the code that the error occurred on, by calling the sys library’s exc_info() method:

1
2
3
4
5

   

# get details about the exception
    err_type, err_obj, traceback = sys.exc_info()

    # get the line number when exception occured
    line_num = traceback.tb_lineno

Print the details for the psycopg2 exception

Use Python’s print() function to print the details of the psycopg2 exception that was passed to the function call:

1
2
3
4
5
6
7
8
9
10

   

# print the connect() error
    print («\npsycopg2 ERROR:», err, «on line number:», line_num)
    print («psycopg2 traceback:», traceback, «— type:», err_type)

    # psycopg2 extensions.Diagnostics object attribute
    print («\nextensions.Diagnostics:», err.diag)

    # print the pgcode and pgerror exceptions
    print («pgerror:», err.pgerror)
    print («pgcode:», err.pgcode, «\n«)

Handle psycopg2 exceptions that occur while connecting to PostgreSQL

Now that the function has been defined it’s time to test it out by running some psycopg2 code. The following Python code attempts to make a connection to PostgreSQL in a try-except indentation block, and, in the case of an exception, passes the TypeError Python object to the print_psycopg2_exception() function defined earlier:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

# declare a new PostgreSQL connection object
try:
    conn = connect(
        dbname = «python_test»,
        user = «WRONG_USER»,
        host = «localhost»,
        password = «mypass»
    )
except OperationalError as err:
    # pass exception to function
    print_psycopg2_exception(err)

    # set the connection to ‘None’ in case of error
    conn = None

NOTE: The above code will give the connection object a value of None in the case of an exception.

If the username string, passed to the user parameter, doesn’t match any of the users for the PostgreSQL server then the function should print something that closely resembles the following:

1
2
3
4
5
6
7
8

psycopg2 ERROR: FATAL:  password authentication failed for user «WRONG_USER»
FATAL:  password authentication failed for user «WRONG_USER»
 on line number: 43
psycopg2 traceback: <traceback object at 0x7fa361660a88> — type: <class ‘psycopg2.OperationalError’>

extensions.Diagnostics: <psycopg2.extensions.Diagnostics object at 0x7fa3646e1558>
pgerror: None
pgcode: None

Handle psycopg2 exceptions that occur while executing SQL statements

If the code to connect to PostgreSQL didn’t have any problems, and no exceptions were raised, then test out the function again. The following code purposely attempts to use a cursor object to execute() a SQL statement with bad syntax:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# if the connection was successful
if conn != None:

    # declare a cursor object from the connection
    cursor = conn.cursor()
    print («cursor object:», cursor, «\n«)

    # catch exception for invalid SQL statement
    try:
        cursor.execute(«INVALID SQL STATEMENT»)
    except Exception as err:
        # pass exception to function
        print_psycopg2_exception(err)

        # rollback the previous transaction before starting another
        conn.rollback()

The print_psycopg2_exception() function should print a response that resembles the following:

1
2
3
4
5
6
7
8
9
10
11
12

psycopg2 ERROR: syntax error at or near «INVALID»
LINE 1: INVALID SQL STATEMENT
        ^
 on line number: 90
psycopg2 traceback: <traceback object at 0x7f58dd244188> — type: <class ‘psycopg2.errors.SyntaxError’>

extensions.Diagnostics: <psycopg2.extensions.Diagnostics object at 0x7f58e0018558>
pgerror: ERROR:  syntax error at or near «INVALID»
LINE 1: INVALID SQL STATEMENT
        ^

pgcode: 42601

The 42601 PostgreSQL code indicates that the exception resulted from a syntax error in the SQL statement:

Screenshot of the PostgreSQL Error Codes web page in a browser tab

Catch ‘InFailedSqlTransaction’ psycopg2 exceptions

This last bit of Python code will raise a InFailedSqlTransaction exception if the last PostgreSQL transaction, with the bad SQL statement, wasn’t rolled back using the connection object’s rollback() method:

1
2
3
4
5
6

# returns ‘psycopg2.errors.InFailedSqlTransaction’ if rollback() not called
    try:
        cursor.execute(«SELECT * FROM some_table;»)
    except errors.InFailedSqlTransaction as err:
        # pass exception to function
        print_psycopg2_exception(err)

Conclusion

The psycopg2 library adapter for PostgreSQL has an extensive list of exception Python classes, and this article only covered a few of them just to give a general idea of how you can handle such exceptions in your own Python script.

Just the Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

# import sys to get more detailed Python exception info
import sys

# import the connect library for psycopg2
from psycopg2 import connect

# import the error handling libraries for psycopg2
from psycopg2 import OperationalError, errorcodes, errors

# import the psycopg2 library’s __version__ string
from psycopg2 import __version__ as psycopg2_version
«`python
#!/usr/bin/python3
# -*- coding: utf-8 -*-

# import sys to get more detailed Python exception info
import sys

# import the connect library for psycopg2
from psycopg2 import connectDoes NOT need TextBroker to re-write

# import the error handling libraries for psycopg2
from psycopg2 import OperationalError, errorcodes, errors

# import the psycopg2 library’s __version__ string
from psycopg2 import __version__ as psycopg2_version

# print the version string for psycopg2
print («psycopg2 version:», psycopg2_version, «\n«)

# define a function that handles and parses psycopg2 exceptions
def print_psycopg2_exception(err):
    # get details about the exception
    err_type, err_obj, traceback = sys.exc_info()

    # get the line number when exception occured
    line_num = traceback.tb_lineno

    # print the connect() error
    print («\npsycopg2 ERROR:», err, «on line number:», line_num)
    print («psycopg2 traceback:», traceback, «— type:», err_type)

    # psycopg2 extensions.Diagnostics object attribute
    print («\nextensions.Diagnostics:», err.diag)

    # print the pgcode and pgerror exceptions
    print («pgerror:», err.pgerror)
    print («pgcode:», err.pgcode, «\n«)

try:
    conn = connect(
        dbname = «python_test»,
        user = «objectrocket»,
        host = «localhost»,
        password = «mypass»
    )
except OperationalError as err:
    # pass exception to function
    print_psycopg2_exception(err)

    # set the connection to ‘None’ in case of error
    conn = None

# if the connection was successful
if conn != None:

    # declare a cursor object from the connection
    cursor = conn.cursor()
    print («cursor object:», cursor, «\n«)

    # catch exception for invalid SQL statement
    try:
        cursor.execute(«INVALID SQL STATEMENT»)
    except Exception as err:
        # pass exception to function
        print_psycopg2_exception(err)

        # rollback the previous transaction before starting another
        conn.rollback()

    # execute a PostgreSQL command to get all rows in a table
    # returns ‘psycopg2.errors.InFailedSqlTransaction’ if rollback() not called
    try:
        cursor.execute(«SELECT * FROM some_table;»)
    except errors.InFailedSqlTranroughsaction as err:
        # pass exception to function
        print_psycopg2_exception(err)

    # close the cursor object to avoid memory leaks
    cursor.close()

    # close the connection object also
    conn.close()

Pilot the ObjectRocket Platform Free!

Try Fully-Managed CockroachDB, Elasticsearch, MongoDB, PostgreSQL (Beta) or Redis.

Get Started


There are many sources of errors. A few examples are a syntax error in an executed SQL statement, a connection failure, or calling the fetch method for an already canceled or finished statement handle.

The DB API defines a number of errors that must exist in each database module. The following table lists these exceptions.

Sr.No. Exception & Description
1

Warning

Used for non-fatal issues. Must subclass StandardError.

2

Error

Base class for errors. Must subclass StandardError.

3

InterfaceError

Used for errors in the database module, not the database itself. Must subclass Error.

4

DatabaseError

Used for errors in the database. Must subclass Error.

5

DataError

Subclass of DatabaseError that refers to errors in the data.

6

OperationalError

Subclass of DatabaseError that refers to errors such as the loss of a connection to the database. These errors are generally outside of the control of the Python scripter.

7

IntegrityError

Subclass of DatabaseError for situations that would damage the relational integrity, such as uniqueness constraints or foreign keys.

8

InternalError

Subclass of DatabaseError that refers to errors internal to the database module, such as a cursor no longer being active.

9

ProgrammingError

Subclass of DatabaseError that refers to errors such as a bad table name and other things that can safely be blamed on you.

10

NotSupportedError

Subclass of DatabaseError that refers to trying to call unsupported functionality.

Your Python scripts should handle these errors, but before using any of the above exceptions, make sure your MySQLdb has support for that exception. You can get more information about them by reading the DB API 2.0 specification.

Kickstart Your Career

Get certified by completing the course

Get Started

Понравилась статья? Поделить с друзьями:
  • Обращение к авторитету логическая ошибка
  • Обратно пошел сильный дождь ошибка
  • Обработка ошибок spring mvc
  • Обратная ошибка хиндсайта
  • Обращение гуманно ошибки исправлены друзья образованы история безнравственна