You are on page 1of 26

Using Python to access DB2 for Linux

Open source programming, serious databases


Skill Level: Intermediate Patrick O'Brien (pobrien@orbtech.com) Studio B

17 Dec 2002 The Python Database API is a standard specification for the implementation of a Python interface to a database management system. The DB2 module is an implementation of the Python Database standard. This tutorial covers the entire API and provides sample code that can be run in Python's interactive mode. It uses the sample database that ships with DB2 UDB 8.1 Enterprise Edition for Linux.

Section 1. Introduction
Should I take this tutorial?
This tutorial was written with two types of people in mind: Python programmers who want to access DB2 V8.1 databases from their Python programs. Database developers who are interested in Python and want to see how it works with DB2. Python is a great tool to use with DB2. It combines the ability to quickly and simply access a DB2 database with the power to perform more complex tasks that require a general purpose programming language. This tutorial shows you everything you need to know to interact with DB2 V8.1 using the Python programming language. In particular, you'll learn about the Python DB2 module, which allows you to connect to
Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved. Trademarks Page 1 of 26

developerWorks

ibm.com/developerWorks

a DB2 database, execute queries, fetch results, and commit or rollback transactions. To keep things as simple as possible, you won't have to build an entire application or write a lot of code. Instead, you'll be shown short, simple examples that can be run directly in Python using the sample database that comes with DB2. By the end of the tutorial you will have received a thorough introduction to the entire Python DB2 interface. To get the most out of this tutorial, you should be familiar with basic relational database concepts and SQL, and have some programming knowledge. Experience with DB2 and Python would be helpful, but are not essential. If you can formulate an SQL query and understand basic programming logic, you should be able to follow this tutorial.

What is this tutorial about?


This tutorial focuses on using the Python DB2 module to access IBM's DB2 database management system (DBMS). With the Python DB2 module you can write programs that access, display, and update the information in a DB2 database. By the end of the tutorial you should be comfortable interacting with a DB2 database using Python. Specifically, this tutorial will show you how to: Connect to a DB2 database Create cursors Execute queries and other SQL statements Interact with and display result sets Commit and rollback transactions Close down cursors and connections

Tools
This tutorial uses the following software. Make sure they are installed and running correctly before starting this tutorial: DB2 UDB Version 8.1. You can download a DB2 from the developerWorks downloads page. The tutorial uses the SAMPLE database that is created during a typical DB2 installation. Python (version 2.2 or higher is recommended).

Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved.

Trademarks Page 2 of 26

ibm.com/developerWorks

developerWorks

PyDB2 Package, which contains the Python DB2 interface module and utilities. Also see Project: PyDB2, which contains additional information about the package. Over the course of the tutorial we will explore the entire database API and some additional utilities. Along the way you will be given code examples that you can execute yourself. All the examples are demonstrated using Python's interactive mode in order to illustrate the results of each command. The tutorial examples were tested against DB2 UDB 8.1 Enterprise Edition for Linux, using the SAMPLE database. Specifically, DB2 8.1 and Python 2.2.2 were installed on Mandrake 9.0. The techniques shown in this tutorial should work equally well with previous versions of DB2, as well as versions running on other platforms, including RedHat 7.2 or higher, SuSE 7.3 or higher, and SCO Linux 4.0 or higher. Note that the DB2 UDB SAMPLE database is not automatically installed when you install DB2. You can install the SAMPLE database using the First Steps graphical utility, or the db2sampl command line utility. See Resources for detailed information on DB2 Information Center.

Section 2. Python overview


What is Python?
Python is an increasingly popular, general-purpose, object-oriented programming language. Python is free and Open Source, and runs on a multitude of platforms, including Linux, Unix, Windows, and Macintosh. Python has a clean, elegant syntax that many developers find to be a tremendous time-saver. Python also has powerful built-in object types that allow you to express complex ideas in a few lines of easily maintainable code. In addition, Python comes with a standard library of modules that provide extensive functionality and support for file handling, network protocols, threads and processes, XML processing, encryption, object serialization, email and newsgroup message processing, etc. For these reasons, Python is known as coming "with batteries included."

What is the Python DB-API?


The DB-API is a standard for Python modules that provide an interface to a DBMS. This standard ensures that Python programs can use a similar syntax to connect to, and access data from, any supported DBMS, such as MySQL, PostgreSQL, Oracle,

Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved.

Trademarks Page 3 of 26

developerWorks

ibm.com/developerWorks

Sybase, or DB2. Each module is usually tailored to the specific DBMS for which it provides an interface, though there is also an ODBC module that allows access to a variety of storage mechanisms. The Python DB2 module was written by Man-Yong (Bryan) Lee, and complies with the latest Python DB-API standard. The Python DB2 module is pretty much the only game in town when it comes to accessing DB2 from Python. In order to understand how to use this module, we're going to take a quick look at the Python language and some of its features. Then we'll look at the DB2 module and see how to connect to a DB2 database, execute queries, interact with the results, and control transactions. You should try out the examples yourself using Python's interactive mode.

Interactive mode
Python can be used to execute program files, or it can be run interactively, in which you enter lines of code and receive an immediate response from the Python interpreter. To start Python in interactive mode, simply type python at your operating system command line. Python will then display a few lines of information, followed by the Python command prompt (>>>):
$ python Python 2.2.2 (#1, Oct 28 2002, 17:22:19) [GCC 3.2 (Mandrake Linux 9.0 3.2-1mdk)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>>

Working with Python interactively is very similar to working with a Linux or DOS shell. At the Python prompt you can type in a line of Python code, press the Enter key, and get a response back. For example, you can use Python as a simple calculator, adding two integers together:
>>> 2 + 2 4 >>>

As you can see in the previous example, Python responded by displaying the sum of the two values, followed by another prompt. You can also assign values to variables and then manipulate the variables:
>>> a = 3 >>> b = 5 >>> a * b 15 >>>

# The pound character (#) begins a comment.

To leave the Python interpreter and return to the command line, press Ctrl-D
Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved. Trademarks Page 4 of 26

ibm.com/developerWorks

developerWorks

under Linux or Ctrl-Z under Windows.

Displaying variable values


Python's interactive mode has a very handy feature that you will see used in several of the examples. When you enter a line of code at the Python prompt that consists of nothing more than the name of a variable, Python responds by displaying a representation of that variable's value. Here are some examples that illustrate this feature:
>>> a = 3 >>> b = 5 >>> c = a * b >>> c 15 >>> d = c / 2.5 >>> d 6.0 >>> e = 'Hello' >>> e 'Hello' >>> f = e * a >>> f 'HelloHelloHello' >>>

Multi-line commands
Some Python code requires multiple lines, such as the block of code that gets executed inside a for loop. In these cases, the Python shell displays a continuation prompt (...) for each subsequent line. Notice also that a block of code is determined by its level of indentation, rather than curly braces or BEGIN and END keywords. In the following example, the lines of code that make up the for loop block are all indented to the same level (typically four spaces). Pressing Enter twice in a row tells Python that you're done entering code and are ready for it to be executed:
>>> for n in range(4): ... print "The first value of n:", n ... print "Multiplied by itself:", n * n ... print "-----------------------" ... The first value of n: 0 Multiplied by itself: 0 ----------------------The first value of n: 1 Multiplied by itself: 1 ----------------------The first value of n: 2 Multiplied by itself: 4 -----------------------

Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved.

Trademarks Page 5 of 26

developerWorks

ibm.com/developerWorks

The first value of n: 3 Multiplied by itself: 9 ---------------------->>>

The built-in range() function used in the previous example returns a list of integer values, which the for loop then iterates over, temporarily assigning each value to the n variable. In Python, a list is denoted by square brackets enclosing a sequence of items separated by commas. In the following example, executing the range() function by itself returns a list of integers:
>>> range(4) [0, 1, 2, 3]

Python has a rich set of built-in object types, and the Python DB2 interface makes heavy use of certain ones. So you need to be able to at least recognize them and understand what they represent. Therefore, the following pages will describe the more common types, such as integers, floats, strings, lists, tuples, and modules.

Integers, floats and strings


Integers and floating point numbers are the most common numeric types supported by Python. Unlike the DB2 data types, Python's floating point numbers do not have a fixed precision or scale.
>>> a = 2 >>> b = 2.345 >>> # an integer # a float

Strings in Python are sequences of characters. You create a string literal by enclosing the characters in single ('), double (") or triple (''' or """) quotes. The triple-quoted forms preserve embedded new lines:
>>> sql1 = 'SELECT * FROM ORG' >>> sql2 = "SELECT * FROM ORG" >>> sql3 = """SELECT * ... FROM ORG ... WHERE DEPTNUMB > 20""" >>> sql3 'SELECT *\nFROM ORG\nWHERE DEPTNUMB > 20' >>>

A Python string is an object that has several built-in capabilities. For example, one of them is the ability to return a copy of itself with all uppercase letters. These capabilities are known as methods. You invoke a method of an object, such as a string, using a dot syntax. That is, you type the name of the variable (which in this

Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved.

Trademarks Page 6 of 26

ibm.com/developerWorks

developerWorks

case is a reference to a string object) followed by the dot (.) operator, then the name of the method followed by opening and closing parentheses:
>>> sql = 'select * from org' >>> sql.upper() 'SELECT * FROM ORG' >>>

Lists and tuples


Lists and tuples are both sequences of arbitrary Python objects. The only substantial difference between the two is that a list is mutable, while a tuple is not. That means a list can be extended, and list items can be inserted, deleted or replaced. A tuple, on the other hand, cannot--its size is fixed once it is created. Lists and tuples have slightly different appearances. Lists are written as a series of objects, separated by commas, inside of square brackets. Tuples are written as a series of objects, separated by commas, inside of parentheses:
>>> mylist = [1, 2, "Buckle", "Shoe"] >>> mytuple = (1, 2, "Buckle", "Shoe") >>> nested = [(1, "Buckle"), (2, "Shoe"), (3, "Shut")] >>>

Lists and tuples can both be referenced by index position (starting with zero). And lists have methods that tuples do not, such as the append() method for adding a new element to the end of the list:
>>> 1 >>> (2, >>> >>> [1, >>> mylist[0] nested[1] 'Shoe') mylist.append("Shut") mylist 2, 'Buckle', 'Shoe', 'Shut']

None
Python has a None type used to represent null or nil. SQL has a NULL value that is used to represent a missing or unknown value. When a DB2 query returns NULL values, they are represented in Python by the None type. None is also quite often used to represent a certain condition in Python. For example, one of the DB2 interface functions will return None when there are no more rows to fetch from a query result set.

Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved.

Trademarks Page 7 of 26

developerWorks

ibm.com/developerWorks

Modules
Modules are simply text files containing Python code that is intended to be used by other programs or at the interactive prompt. To make use of a module, you load it into memory with the import statement. While the physical file has a .py suffix, Python refers to the module without the suffix. Here is how you import the DB2 module (whose filename is DB2.py):
>>> import DB2 >>>

Once a module is imported, you may use any of its contents. To do so, you simply preface the variable's name with the module name separated by a dot (.):
>>> DB2.apilevel '2.0' >>> DB2.paramstyle 'qmark' >>>

Section 3. Python DB2 module


DB2 interaction overview
Now that you've been introduced to Python, you're ready to start accessing DB2. The process for retrieving information from a DB2 database is fairly simple, and is composed of the following steps: 1. 2. 3. 4. 5. 6. Import the DB2 module Create a connection Create a cursor Execute a query on the cursor Fetch the returned rows from the cursor Handle any exceptions
Trademarks Page 8 of 26

Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved.

ibm.com/developerWorks

developerWorks

7. 8. 9.

Repeat as necessary Close the cursor Close the connection

Let's look at a simple example; then we'll go into the details of each step.

DB2 interaction example


Here is a simple example that illustrates an entire interaction with a DB2 database, from beginning to end:
>>> import DB2 >>> conn = DB2.connect(dsn='sample', uid='db2inst1', pwd='******') >>> curs = conn.cursor() >>> curs.execute('SELECT * FROM ORG') >>> rows = curs.fetchall() >>> rows [(10, 'Head Office', 160, 'Corporate', 'New York'), (15, 'New England', 50, 'Eastern', 'Boston'), (20, 'Mid Atlantic', 10, 'Eastern', 'Washington'), (38, 'South Atlantic', 30, 'Eastern', 'Atlanta'), (42, 'Great Lakes', 100, 'Midwest', 'Chicago'), (51, 'Plains', 140, 'Midwest', 'Dallas'), (66, 'Pacific', 270, 'Western', 'San Francisco'), (84, 'Mountain', 290, 'Western', 'Denver')] >>> curs.close() >>> conn.close() >>>

The Python code is straightforward and hardly needs explaining. Nevertheless, there are several options and variations that you should understand, starting with establishing a connection to a particular database.

Connection objects
The first step in accessing a DB2 database is to establish a connection to a particular data source, as a particular user. To do so you create a connection object, passing in the required arguments:
>>> import DB2 >>> conn = DB2.connect(dsn='sample', uid='db2inst1', pwd='******') >>>

The connect() constructor accepts the following parameters:

Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved.

Trademarks Page 9 of 26

developerWorks

ibm.com/developerWorks

dsn - data source name, required uid - user name, required pwd - password, required autocommit - optional, defaults to True connecttype - optional, defaults to 1 When a connection object is no longer needed, you should call its close() method, which will free up resources. The next panel describes all the parameters in detail.

Connection parameters
The data source (dsn), user name (uid), and password (pwd) parameters should be obvious to anyone familiar with databases. The password argument shown in the examples has been obscured. You should use appropriate values for your own environment. A real application would likely store these arguments in a configuration file, accept them as command line options, or prompt the user for values. The autocommit parameter allows you to control the automatic committing of transactions. By default, a connection object will automatically commit each interaction with the database. If you want to determine your own transaction boundaries, you can supply a different autocommit argument value or use the connection's autocommit() method to toggle the autocommit feature:
>>> conn.autocommit() # Get the current value. 1 >>> conn.autocommit(False) # Set to False. 0 >>> conn.autocommit(True) # Set to True. 1 >>>

To support transactions, the connection object provides commit() and rollback() methods. These will be discussed with Transactions . The connecttype parameter takes one of two values: 1 sets the connection type to a remote unit of work (default); 2 sets it to a distributed unit of work.

Cursor objects
Once a connection to the database is established, you can use it to create one or

Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved.

Trademarks Page 10 of 26

ibm.com/developerWorks

developerWorks

more cursors. A cursor is used to send SQL statements (SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER) to the database. To create a cursor, you simply call the connection object's cursor() method, which returns a cursor object:
>>> import DB2 >>> conn = DB2.connect(dsn='sample', uid='db2inst1', pwd='******') >>> curs = conn.cursor() >>>

Cursor objects provide an execute() method that accepts an SQL statement. When called, the SQL statement is sent to the DBMS to be executed. If the statement was a SELECT query, the results can then be retrieved using one of the fetch methods: fetchone(), fetchmany(), and fetchall(). We'll look at the fetch methods in detail next. Note that the execute() function does not return a value:
>>> >>> >>> >>> >>> import DB2 conn = DB2.connect(dsn='sample', uid='db2inst1', pwd='******') curs = conn.cursor() curs.execute('SELECT * FROM ORG')

Fetching results
Once a SELECT query has been executed by the cursor object, the results can be retrieved, or fetched, from the DBMS. The fetchone() method returns a single row from the SELECT result set. The row's contents are returned in the form of a Python tuple (not to be confused with a relational tuple):
>>> curs.execute('SELECT * FROM ORG') >>> curs.fetchone() (10, 'Head Office', 160, 'Corporate', 'New York') >>>

The fetchall() and fetchmany() methods return a list of tuples, with each tuple representing one row. The fetchmany() method accepts a single argument specifying the maximum number of rows to return:
>>> curs.execute('SELECT * FROM ORG') >>> curs.fetchmany(3) [(10, 'Head Office', 160, 'Corporate', 'New York'), (15, 'New England', 50, 'Eastern', 'Boston'), (20, 'Mid Atlantic', 10, 'Eastern', 'Washington')] >>>

Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved.

Trademarks Page 11 of 26

developerWorks

ibm.com/developerWorks

If more rows are specified than are available, fetchmany() returns as many rows as it can:
>>> curs.execute('SELECT * FROM ORG') >>> curs.fetchmany(300) [(10, 'Head Office', 160, 'Corporate', 'New York'), (15, 'New England', 50, 'Eastern', 'Boston'), (20, 'Mid Atlantic', 10, 'Eastern', 'Washington'), (38, 'South Atlantic', 30, 'Eastern', 'Atlanta'), (42, 'Great Lakes', 100, 'Midwest', 'Chicago'), (51, 'Plains', 140, 'Midwest', 'Dallas'), (66, 'Pacific', 270, 'Western', 'San Francisco'), (84, 'Mountain', 290, 'Western', 'Denver')] >>>

Cursor position
Every time a row is fetched, the position in the result set moves to the next row. That means the entire set of rows can be returned by repeated calls to fetchone(), or a combination of any of the fetch methods. Once a cursor has been exhausted, subsequent calls to fetchone() return None; fetchmany() and fetchall() return empty lists ([]):
>>> curs.execute('SELECT * FROM ORG') >>> while True: ... org = curs.fetchone() ... if org is None: ... print "**** The End ****" ... break ... print org ... (10, 'Head Office', 160, 'Corporate', 'New York') (15, 'New England', 50, 'Eastern', 'Boston') (20, 'Mid Atlantic', 10, 'Eastern', 'Washington') (38, 'South Atlantic', 30, 'Eastern', 'Atlanta') (42, 'Great Lakes', 100, 'Midwest', 'Chicago') (51, 'Plains', 140, 'Midwest', 'Dallas') (66, 'Pacific', 270, 'Western', 'San Francisco') (84, 'Mountain', 290, 'Western', 'Denver') **** The End **** >>> curs.fetchmany() [] >>> curs.fetchall() [] >>>

Beyond SELECT queries


The execute() method works with any valid SQL statement. So, for example, you can execute a CREATE TABLE query:
>>> sql = """

Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved.

Trademarks Page 12 of 26

ibm.com/developerWorks

developerWorks

... CREATE TABLE TEST ( ... No CHARACTER(03) ... Name VARCHAR(20) ... Desc VARCHAR(100), ... PRIMARY KEY(No) ... );""" >>> print sql CREATE TABLE TEST ( No CHARACTER(03) Name VARCHAR(20) Desc VARCHAR(100), PRIMARY KEY(No) ); >>> curs.execute(sql) >>>

NOT NULL, NOT NULL,

NOT NULL, NOT NULL,

Attempting to fetch a result from any type of query other than a SELECT query will raise a Python exception. For example, this is what happens if we call fetchall() after the previous CREATE TABLE query:
>>> curs.fetchall() Traceback (most recent call last): File "<input>", line 1, in ? File "/usr/local/lib/python2.2/site-packages/DB2.py", line 415, in fetchall one_row = self.fetchone() File "/usr/local/lib/python2.2/site-packages/DB2.py", line 350, in fetchone raw_data = self._cs.fetchone() error: No data >>>

Cursor object properties


The cursor object exposes a variety of properties that provide valuable information about the previously executed query, particularly with SELECT queries. The colcount property indicates the number of columns in the result set:
>>> curs.execute('SELECT * FROM ORG') >>> curs.colcount 5 >>>

The description property is a tuple of tuples, describing each column in the result set. Each inner tuple represents one column and contains seven items of information: 1. 2. column name type code

Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved.

Trademarks Page 13 of 26

developerWorks

ibm.com/developerWorks

3. 4. 5. 6. 7.

display size internal size precision scale (zero for non-numeric types) NULL values allowed

The description property is easier to understand when looking at a real example:


>>> curs.execute('SELECT * FROM ORG') >>> curs.description (('DEPTNUMB', 5, 6, 6, 5, 0, 0), ('DEPTNAME', 12, 14, 14, 14, 0, 1), ('MANAGER', 5, 6, 6, 5, 0, 1), ('DIVISION', 12, 10, 10, 10, 0, 1), ('LOCATION', 12, 13, 13, 13, 0, 1)) >>>

Because the column's type code isn't very meaningful, the DB2 module also provides a description2 property for cursors, which substitutes a text value for the type code:
>>> curs.description2 (('DEPTNUMB', 'SQL_SMALLINT', 6, 6, 5, 0, 0), ('DEPTNAME', 'SQL_VARCHAR', 14, 14, 14, 0, 1), ('MANAGER', 'SQL_SMALLINT', 6, 6, 5, 0, 1), ('DIVISION', 'SQL_VARCHAR', 10, 10, 10, 0, 1), ('LOCATION', 'SQL_VARCHAR', 13, 13, 13, 0, 1)) >>>

The db2util module makes extensive use of the column information provided by the description property to create a nice format for query results. The following example illustrates one use of this in the cprint() function:
>>> from PyDB2 import db2util >>> import DB2 >>> conn = DB2.connect(dsn='sample', uid='db2inst1', pwd='******') >>> curs = conn.cursor() >>> curs.execute('SELECT * FROM ORG') >>> db2util.cprint(curs, curs.fetchall()) DEPTNUMB DEPTNAME MANAGER DIVISION LOCATION -------- -------------- ------- ---------- ------------10 Head Office 160 Corporate New York 15 New England 50 Eastern Boston 20 Mid Atlantic 10 Eastern Washington 38 South Atlantic 30 Eastern Atlanta 42 Great Lakes 100 Midwest Chicago 51 Plains 140 Midwest Dallas 66 Pacific 270 Western San Francisco

Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved.

Trademarks Page 14 of 26

ibm.com/developerWorks

developerWorks

84 Mountain >>>

290 Western

Denver

Query parameters
So far we've shown very simple queries in our examples. But most applications will need to execute queries with variable data, based on user input or values determined at runtime. The DB2 interface supports the use of parameters within queries, and will make sure that string parameter values are properly quoted. The particular parameter style supported is the question mark style, where question marks are used as placeholders for parameters. To make use of parameters in your queries, simply insert question marks in your SQL statement wherever you want a parameter value to appear. Then you supply the cursor's execute() method with a tuple of parameter values along with your SQL statement. The following example demonstrates one use of this technique:
>>> sql = 'SELECT * FROM ORG WHERE DEPTNUMB = ? OR DIVISION = ?' >>> dept = 84 >>> div = 'Midwest' >>> curs.execute(sql, (dept, div)) >>> curs.fetchall() [(42, 'Great Lakes', 100, 'Midwest', 'Chicago'), (51, 'Plains', 140, 'Midwest', 'Dallas'), (84, 'Mountain', 290, 'Western', 'Denver')] >>>

Note that parameters can be used with any SQL statement and are not limited to SELECT queries. In fact, parameters can be quite handy with INSERT queries, which we will see in the next panel where we talk about executing multiple SQL statements.

Executing multiple statements


In addition to the execute() method, the cursor object also provides an executemany() method. The difference between these two methods is that executemany() takes a sequence of parameter tuples in addition to an SQL statement. The SQL statement is then executed once for each tuple of parameters in the sequence. Basically, the executemany() method can be seen as a simpler way of calling execute() several times with different parameter values. In fact, that is how the executemany() method is implemented. In addition, the entire set of executions is wrapped inside a single transaction, such that either all of the statements are applied to the database or none of them are applied.

Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved.

Trademarks Page 15 of 26

developerWorks

ibm.com/developerWorks

As you can imagine, the executemany() method doesn't make much sense with a SELECT query. Instead, you would use executemany() to perform multiple INSERT or UPDATE queries. Let's take a look at the executemany() method in action. In an earlier example we created a TEST table:
>>> sql = """ ... CREATE TABLE TEST ( ... No CHARACTER(03) ... Name VARCHAR(20) ... Desc VARCHAR(100), ... PRIMARY KEY(No) ... );""" >>> curs.execute(sql) >>>

NOT NULL, NOT NULL,

Now we would like to populate the TEST table with some test data. So we'll create a list of parameter value tuples and send that list to the executemany() method, along with an INSERT statement:
>>> sql = "INSERT INTO TEST VALUES(?, ?, ?)" >>> plist = [('%03d' % i, 'TEST%03d' % i, 'Test record %s.' % i) ... for i in range(5)] >>> plist [('001', 'TEST001', 'Test record 1.'), ('002', 'TEST002', 'Test record 2.'), ('003', 'TEST003', 'Test record 3.'), ('004', 'TEST004', 'Test record 4.')] >>> curs.executemany(sql, plist) 4 >>> curs.execute('Select * from TEST') >>> curs.fetchall() [('001', 'TEST001', 'Test record 1.'), ('002', 'TEST002', 'Test record 2.'), ('003', 'TEST003', 'Test record 3.'), ('004', 'TEST004', 'Test record 4.')] >>>

The DB-API standard does not define a return value for executemany(), but as you can see in the previous example, the DB2 interface returns a count of the number of successful executions, or zero if there was a problem requiring a transaction rollback.

Transactions
A transaction combines a series of commands such that either all of them are executed or none of them are executed (and the database is returned to its original state). To support this capability, a connection object has two methods: commit() makes permanent any pending changes; rollback() discards any pending changes. A transactions starts implicitly at cursor creation time and after each call to

Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved.

Trademarks Page 16 of 26

ibm.com/developerWorks

developerWorks

commit() or rollback(). A transaction in one connection is independent of transactions in other connections. Cursors are associated with a particular connection. Multiple cursors associated with the same connection are all part of the same transaction. Therefore, changes made in one cursor are visible to all other cursors that share the same connection. Transactions can span multiple calls to execute(). The basic idea is to create a connection, create one or more cursors for that connection, then execute one or more SQL statements using the cursors. Depending on the results of those commands, a decision will be made to either commit the transaction or roll back any changes.

Transaction example
Here is a simple example of the transaction process:
>>> import DB2 >>> conn = DB2.connect(dsn='sample', uid='db2inst1', ... pwd='******', autocommit=False) >>> curs = conn.cursor() >>> sql = 'UPDATE ORG SET DEPTNAME = ? WHERE DEPTNUMB = ?' >>> curs.execute(sql, ('Main Office', 10)) 1 >>> sql = 'UPDATE ORG SET LOCATION = ? WHERE DEPTNAME = ?' >>> curs.execute(sql, ('St. Louis', 'Plains')) 1 >>> curs.execute('SELECT * FROM ORG') >>> curs.fetchall() [(10, 'Main Office', 160, 'Corporate', 'New York'), (15, 'New England', 50, 'Eastern', 'Boston'), (20, 'Mid Atlantic', 10, 'Eastern', 'Washington'), (38, 'South Atlantic', 30, 'Eastern', 'Atlanta'), (42, 'Great Lakes', 100, 'Midwest', 'Chicago'), (51, 'Plains', 140, 'Midwest', 'St. Louis'), (66, 'Pacific', 270, 'Western', 'San Francisco'), (84, 'Mountain', 290, 'Western', 'Denver')] >>> conn.rollback() >>> curs.execute('SELECT * FROM ORG') >>> curs.fetchall() [(10, 'Head Office', 160, 'Corporate', 'New York'), (15, 'New England', 50, 'Eastern', 'Boston'), (20, 'Mid Atlantic', 10, 'Eastern', 'Washington'), (38, 'South Atlantic', 30, 'Eastern', 'Atlanta'), (42, 'Great Lakes', 100, 'Midwest', 'Chicago'), (51, 'Plains', 140, 'Midwest', 'Dallas'), (66, 'Pacific', 270, 'Western', 'San Francisco'), (84, 'Mountain', 290, 'Western', 'Denver')] >>>

Empty result sets


Sometimes a SELECT query will return an empty result set. In this case, the cursor's

Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved.

Trademarks Page 17 of 26

developerWorks

ibm.com/developerWorks

fetchall() and fetchmany() methods will return an empty list ([]):


>>> curs.execute('SELECT * FROM STAFF WHERE 1=0') >>> rows = curs.fetchall() >>> print rows [] >>>

In the same situation, the cursor's fetchone() method will return None:
>>> curs.execute('SELECT * FROM STAFF WHERE 1=0') >>> row = curs.fetchone() >>> print row None >>>

Case sensitivity
Case sensitivity can sometimes trip up newcomers. For the record, Python is case sensitive while SQL, for the most part, is not. Note that, in DB2, quoted identifiers (such as table names) are also case sensitive, as demonstrated in the following example:
>>> curs.execute('SELECT * FROM STAFF') # Uppercase works fine. >>> curs.execute('SELECT * FROM staff') # As does lowercase. >>> curs.execute('SELECT * FROM "STAFF"') # This quoted name works. >>> curs.execute('SELECT * FROM "staff"') # But lowercase does not. Traceback (most recent call last): File "<input>", line 1, in ? File "/home/pobrien/Code/PyDB2/DB2.py", line 311, in execute ret = self._cs.execute(stmt) error: SQLSTATE : 42S02, NATIVE ERROR CODE : -204 [IBM][CLI Driver][DB2/LINUX] SQL0204N SQLSTATE=42704 >>> "DB2INST1.staff" is an undefined name.

Section 4. Python DB2 utilities


The db2util module
Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved. Trademarks Page 18 of 26

ibm.com/developerWorks

developerWorks

The db2util module provides a few utilities that make it easier to work with the DB2 interface. The entire source code is provided below. The rest of this section highlights the most useful functions and show examples of their use.
"""Utilities for use with DB2 and the Python DB2 interface.""" __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" __cvsid__ = "$Id: db2util.py,v 1.2 2002/12/04 00:38:09 pobrien Exp $" __revision__ = "$Revision: 1.2 $"[11:-2] import DB2 SQLTYPES = ( 'SQL_BIGINT', 'SQL_BINARY', 'SQL_BLOB', 'SQL_BLOB_LOCATOR', 'SQL_CHAR', 'SQL_CLOB', 'SQL_CLOB_LOCATOR', 'SQL_TYPE_DATE', 'SQL_DBCLOB', 'SQL_DBCLOB_LOCATOR', 'SQL_DECIMAL', 'SQL_DOUBLE', 'SQL_FLOAT', 'SQL_GRAPHIC', 'SQL_INTEGER', 'SQL_LONGVARCHAR', 'SQL_LONGVARBINARY', 'SQL_LONGVARGRAPHIC', 'SQL_NUMERIC', 'SQL_REAL', 'SQL_SMALLINT', 'SQL_TYPE_TIME', 'SQL_TYPE_TIMESTAMP', 'SQL_VARCHAR', 'SQL_VARBINARY', 'SQL_VARGRAPHIC', ) BINARYTYPES = ( 'SQL_BLOB', 'SQL_BLOB_LOCATOR', 'SQL_CLOB', 'SQL_CLOB_LOCATOR', 'SQL_DBCLOB', 'SQL_DBCLOB_LOCATOR', 'SQL_GRAPHIC', 'SQL_LONGVARBINARY', 'SQL_LONGVARGRAPHIC', 'SQL_VARBINARY', 'SQL_VARGRAPHIC' ) def connect(dsn='sample', uid='db2inst1', pwd='ibmdb2', autocommit=True, connecttype=1): """Return connection to DB2.""" conn = DB2.connect(dsn, uid, pwd, autocommit, connecttype) return conn def fp(cursor, sep=' ', null=''): """Fetch and print all rows returned by cursor.

Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved.

Trademarks Page 19 of 26

developerWorks

ibm.com/developerWorks

cursor is a database cursor sep is the column separator (default is one space) null is the representation for a NULL value (default is an empty string) """ rows = cursor.fetchall() cprint(cursor, rows, sep, null) def cprint(cursor, rows, sep=' ', null=None): """Print rows returned by cursor in a columnar format. cursor is a database cursor rows is a list of tuples returned by cursor.fetch* sep is the column separator (default is one space) null is the representation for a NULL value (default is None) """ columns = cursor.description2 if not columns: return '*** NO QUERY WAS EXECUTED ***' headers = getheaders(columns, sep) # Format the rows. dataformats = getdataformats(columns) textformats = gettextformats(columns) rows = [formatrow(row, dataformats, textformats, sep, null) for row in rows] # Print the final formatted text. print "\n".join(headers + rows) def getheaders(columns, sep): """Return list of headers for columnar display.""" nameheader = getnameheader(columns, sep) # Dashes will separate the names from the values. dashheader = getdashheader(columns, sep) headers = [nameheader, dashheader] return headers def getnameheader(columns, sep): """Return name header.""" names = getnames(columns) textformats = gettextformats(columns) textformat = sep.join(textformats) header = textformat % tuple(names) return header def getdashheader(columns, sep): """Return dash header.""" dashes = getdashes(columns) textformats = gettextformats(columns) textformat = sep.join(textformats) header = textformat % tuple(dashes) return header def getnames(columns): """Return list of names for columns""" names = [column[0] for column in columns] return names def getdashes(columns): """Return list of dashes for columnar display.""" sizes = getdisplaysizes(columns) dashes = ['-' * size for size in sizes] return dashes def getdisplaysizes(columns): """Return list of display sizes required for columns.""" sizes = [getdisplaysize(column) for column in columns] return sizes def getdisplaysize(column): """Return display size required for column."""

Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved.

Trademarks Page 20 of 26

ibm.com/developerWorks

developerWorks

name, type, displaysize, internalsize, precision, scale, nullokay = column size = max(len(name), displaysize) if type in BINARYTYPES: if type in ('SQL_DBCLOB', 'SQL_DBCLOB_LOCATOR'): size = max(len(name), len('<DBCLOB>')) else: size = max(len(name), len('<?LOB>')) return size def gettextformats(columns): """Return list of text format strings for columns.""" sizes = getdisplaysizes(columns) textformats = ['%%-%ss' % size for size in sizes] return textformats def getdataformats(columns): """Return list of data format strings for columns.""" dataformats = [getdataformat(column) for column in columns] return dataformats def getdataformat(column): """Return data format string for column.""" name, type, displaysize, internalsize, precision, scale, nullokay = column size = getdisplaysize(column) if type in ('SQL_DECIMAL', 'SQL_DOUBLE', 'SQL_FLOAT', 'SQL_NUMERIC', 'SQL_REAL'): format = '%%%s.%sf' % (size, scale) elif type in ('SQL_BIGINT', 'SQL_INTEGER', 'SQL_SMALLINT'): format = '%%%si' % (size) elif type in BINARYTYPES: format = '%%-%sr' % (size) else: format = '%%-%ss' % (size) return format def formatrow(row, dataformats, textformats, sep, null=None): """Return row as formatted string, taking into account NULL values.""" row = list(row) formats = [] for n in range(len(row)): if row[n] is None: if null is not None: row[n] = null formats.append(textformats[n]) else: formats.append(dataformats[n]) format = sep.join(formats) row = format % tuple(row) return row

Connecting
The db2util module provides a connect() function that parallels the connect() constructor in the DB2 module. The only difference is that the db2util version provides keyword arguments with useful default values, which can be quite helpful in a Python shell such as IDLE or PyCrust. Also, since a connection is the entry point to all the other DB2 functionality, you have access to everything you need by simply importing the db2util module. Here is the code for the connect() function:
def connect(dsn='sample', uid='db2inst1', pwd='ibmdb2', autocommit=True, connecttype=1):

Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved.

Trademarks Page 21 of 26

developerWorks

ibm.com/developerWorks

"""Return connection to DB2.""" conn = DB2.connect(dsn, uid, pwd, autocommit, connecttype) return conn

Using the db2util connect() function is almost identical to the DB2 module's version:
>>> >>> >>> >>> >>> from PyDB2 import db2util conn = db2util.connect(pwd='******') curs = conn.cursor() curs.execute('SELECT * FROM STAFF')

Fetching and printing


When running SELECT queries you often want to see the results presented in nicely formatted rows and columns. For this, the db2util module provides the fp() function, which stands for "fetch and print." This function requires a cursor object that has already executed a SELECT query, but hasn't fetched any rows yet. Optionally, you may supply a column separator and a value to represent NULL values. The source code is quite short:
def fp(cursor, sep=' ', null=''): """Fetch and print all rows returned by cursor. cursor is a database cursor sep is the column separator (default is one space) null is the representation for a NULL value (default is an empty string) """ rows = cursor.fetchall() cprint(cursor, rows, sep, null)

Here are the results of running fp() with a few different queries:
>>> from PyDB2 import db2util >>> conn = db2util.connect(pwd='******') >>> curs = conn.cursor() >>> from PyDB2.db2util import fp >>> curs.execute('SELECT * FROM ORG') >>> fp(curs) DEPTNUMB DEPTNAME MANAGER DIVISION LOCATION -------- -------------- ------- ---------- ------------10 Head Office 160 Corporate New York 15 New England 50 Eastern Boston 20 Mid Atlantic 10 Eastern Washington 38 South Atlantic 30 Eastern Atlanta 42 Great Lakes 100 Midwest Chicago 51 Plains 140 Midwest Dallas 66 Pacific 270 Western San Francisco 84 Mountain 290 Western Denver >>> curs.execute('SELECT * FROM STAFF WHERE YEARS > 9') >>> fp(curs) ID NAME DEPT JOB YEARS SALARY COMM

Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved.

Trademarks Page 22 of 26

ibm.com/developerWorks

developerWorks

-----50 210 260 290 310 >>>

--------- ------ ----- ------ --------- --------Hanes 15 Mgr 10 20659.80 Lu 10 Mgr 10 20010.00 Jones 10 Mgr 12 21234.00 Quill 84 Mgr 10 19818.00 Graham 66 Sales 13 21000.00 200.30

Cursor printing
The fp() function described in the previous section had very few lines of source code because it relied heavily on the functionality provided by the cprint() function. The cprint() function also expects to receive a cursor object that has already executed a SELECT query, but it also requires the rows returned by one of the fetch methods. Like fp(), you may supply a separator and NULL representation. Looking at the source code reveals the use of the cursor.description2 to determine the column formatting for the result set:
def cprint(cursor, rows, sep=' ', null=None): """Print rows returned by cursor in a columnar format. cursor is a database cursor rows is a list of tuples returned by cursor.fetch* sep is the column separator (default is one space) null is the representation for a NULL value (default is None) """ columns = cursor.description2 if not columns: return '*** NO QUERY WAS EXECUTED ***' headers = getheaders(columns, sep) # Format the rows. dataformats = getdataformats(columns) textformats = gettextformats(columns) rows = [formatrow(row, dataformats, textformats, sep, null) for row in rows] # Print the final formatted text. print "\n".join(headers + rows)

Here is one example of cprint() where we supply a different column separator and NULL representation:
>>> curs.execute('SELECT * FROM STAFF WHERE YEARS > 9') >>> rows = curs.fetchall() >>> db2util.cprint(curs, rows, sep=' | ', null='*********') ID | NAME | DEPT | JOB | YEARS | SALARY | COMM ------ | --------- | ------ | ----- | ------ | --------- | --------50 | Hanes | 15 | Mgr | 10 | 20659.80 | ********* 210 | Lu | 10 | Mgr | 10 | 20010.00 | ********* 260 | Jones | 10 | Mgr | 12 | 21234.00 | ********* 290 | Quill | 84 | Mgr | 10 | 19818.00 | ********* 310 | Graham | 66 | Sales | 13 | 21000.00 | 200.30 >>>

Looking at the source code for cprint(), you can see that it calls upon several other functions defined in the db2util module. While we won't describe the rest of
Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved. Trademarks Page 23 of 26

developerWorks

ibm.com/developerWorks

them in this tutorial, their purpose is readily apparent and the code should be relatively easy to follow. These functions illustrate the use of the DB2 module and provide a solid foundation to build upon. For example, the db2util module could be used in the creation of a graphical query tool.

Section 5. Summary
DB2 and Python summary
This tutorial walked you through the steps involved in accessing DB2 databases using the Python programming language. Specifically, we covered techniques dealing with: Options for connecting to a DB2 database Creating connections and cursors Executing SELECT, INSERT, and UPDATE queries and other SQL statements Interacting with and displaying result sets Autocommiting vs. explicitly committing or canceling transactions Utilities for accessing and displaying DB2 data I hope this tutorial has demonstrated how simple it is to work with DB2 using the Python DB2 module. If you followed all the examples, you should be well on your way to productively combining these two great technologies to build applications that leverage the power and performance of the DB2 DBMS. I'd like to thank Man-Yong (Bryan) Lee, author of the Python DB2 module, for his assistance and for nurturing the DB2 module over the past few years. During the writing of this tutorial, we decided to move the DB2 module to SourceForge, in order to make it more accessible to others. We are happy to announce that the original interface files, plus the new db2util module, are now available at the PyDB2 project. We welcome any developers who would like to improve and extend the use of Python with DB2.

Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved.

Trademarks Page 24 of 26

ibm.com/developerWorks

developerWorks

Resources
Learn For a thorough introduction to the power of Python, see the Python Tutorial by Guido van Rossum, the author of the Python programming language. The Python Database SIG contains links to additional documentation and a mailing list. The DB-API Spec defines the Python Database API Specification. For an overview of using Python and Perl with IBM DB2, see the IBM article The Camel and the Snake. Python Persistence is an article from IBM that discusses alternative persistence mechanisms. IBM's DB2 developer domain is a great place to look for additional DB2 resources for developers. Detailed information on db2sampl and the SAMPLE database is available at the DB2 Information Center. Stay current with developerWorks technical events and webcasts. Get products and technologies The PyDB2 Package contains the Python DB2 interface module and utilities. Project: PyDB2 contains additional information about the package. Build your next development project with IBM trial software, available for download directly from developerWorks. Discuss Participate in the discussion forum for this content.

About the author


Patrick O'Brien Python expert and jack-of-all-trades technologist, Patrick O'Brien, a Studio B client, has been developing software for over 15 years, beginning with MS DOS, then Windows, and now Linux. His very first application used Paradox for DOS, and he has been using databases to solve data management problems ever since. Patrick is actively involved in several Open Source projects that use the Python programming language. He is the author of PyCrust, an interactive, graphical Python shell written in Python using the wxPython GUI toolkit,
Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved. Trademarks Page 25 of 26

developerWorks

ibm.com/developerWorks

a developer of the PythonCard wxPython application construction kit, and leader of the PyPerSyst team, which is working on several object persistence mechanisms for Python applications. His Python articles have been published by O'Reilly and IBM, and he has presented at the O'Reilly Open Source Convention. You can contact Patrick at pobrien@orbtech.com.

Using Python to access DB2 for Linux Copyright IBM Corporation 2002. All rights reserved.

Trademarks Page 26 of 26

You might also like