Just when you thought it was safe to put this book down, download Perl or Tcl, and get going writing Tk applications for Oracle, there’s yet another open source GUI scripted language you have to consider—Python. When used with the DCOracle database access library extension, Python (combined with its Tkinter windowing system) provides another excellent scripted solution for working with Oracle.
Python grew out of Guido van Rossum’s work with the Amoeba distributed operating system and his need to create a more useful tool for Amoeba system administration. He first began working on Python in late 1989 and by 1991 was ready to post it to the Internet. Python grew out of the earlier ABC language and a blend of other design ideas—notably, those based around Modula-3. Van Rossum wanted to create a language that was portable and easy to learn and had a powerful, standard library and the capacity for extension and operating system independence.
People often assume that the Python language is named after the famous snake; however, it is in fact named after one of England’s finest exports, “Monty Python’s Flying Circus.” Python now has a large and independent clan of enthusiastic supporters, and it is Eric Raymond’s choice as the best first language for budding hackers. Python is similar in programming scope to both Perl and Tcl (that is to say, it is without bounds). Python is a fully object-oriented language, which offers as many facilities and modules as are available for Perl and Tcl. The language can be used for whatever programming purpose you can think of (GUIs, XML, email, you name it). Python has now been successfully ported to most other operating systems, including virtually all flavors of Unix, Linux, Win32, and Macintosh.
The following are the main web sites for Python:
The central portal for all things Python
General coverage of various Python database modules
The main interface package between Python and Oracle
On commercial Unix systems, you will usually need to build Python from source. However, many binaries are now appearing for popular vanilla Unix types such as Solaris. There are also several alternatives for Windows installation.
Most Linux distributions already contain at least Python 1.5.2; however, Version 2.0 is expected to quickly become the new standard. If you’d like a later version than you have, you can download some Linux RPMs[26] from http://www.python.org/2.0/.
If you want to install Python from source, you can do so as follows:
To install Python (including the links to Tkinter, which itself
relies upon Tcl/Tk), download the latest version from http://www.python.org/2.0/#download.In our
case, the latest version was Python 2.0. (Note the helpful messages
built into the file name:
BeOpen-Python-2.0.tar.gz.)
Unpack this file to its Python-2.0
home
directory.
To get the Tkinter GUI side of things going, make sure that you’ve previously set up Tcl/Tk (as described earlier in this chapter) and you know which versions you’ve installed. We’ll assume Tk version 8.4 for the rest of our installation steps, which we’ve performed under Linux.
To get Tkinter to work, before you do anything else, make sure the
Python compiler will later be able to pick up the
libtk8.4.so
library file (here we assume
it’s lurking in the /usr/local/lib
directory from the Tcl/Tk build earlier). You do this by ensuring
that the LD_LIBRARY_PATH environment variable is correctly set:
$ LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH $ export LD_LIBRARY_PATH
Before actually configuring Python, you’ll also need to go to
the Python-2.0/Modules
directory and edit the
Setup
file that you’ll find there. In this
file you’ll find various instructions for compiling in the
crucial _tkinter
extensions. You’ll find
that these have been commented out by default (in case you
haven’t already set up Tcl/Tk and don’t want Tkinter).
Since in this case we need the Tkinter
extension to get our DCOracle GUI example to work later on, we must
alter our Setup
file to include everything
necessary for _tkinter
(on Linux):
# The _tkinter module. # The TKPATH variable is always enabled, to save you the effort. TKPATH=:lib-tk _tkinter _tkinter.c tkappinit.c -DWITH_APPINIT -I/usr/local/include -I/usr/X11R6/include -L/usr/local/lib -ltk8.4 -ltcl8.4 -L/usr/X11R6/lib -lX11
You’ll find many useful comments surrounding each line—for example, telling you what the X Windows library alternatives are. The really crucial line is the one detailing which versions of Tk and Tcl you’ll be pointing Python’s Tkinter at (in our case, 8.4 for both). Python 2.0 is preconfigured to work with Tcl/Tk versions 8 and over, so this is OK.
Now we can configure Python, make it, test it, and install it with
all of its requisite libraries (for now, we’ll accept the
default final destination for the Python interpreter, which is
/usr/local/bin/python
. See the
README
file for configuring in alternatives to
this). Here is an outline of the steps:
$ cd Python-2.0 $ ./configure $ make $ make test $ make install
The previous steps will also generate literally hundreds of
compilation messages and test lines, which are excellent for
debugging purposes should anything misbehave. If any of these steps
goes wrong, be sure to sort it out before moving on. The ones to look
out for are those involving the correct setting of LD_LIBRARY_PATH to
get the right Tcl/Tk libraries, and those ensuring that the
.. /Python-2.0/Modules/Setup
file is set
correctly for _tkinter
usage on your particular
flavor of operating system.
Assuming complete success, we should now be ready to get going with
Tkinter. After running through the steps above, you may also want to
confirm that your Python is slithering correctly with Tkinter before
moving on. To do this, run one of the many thoughtfully provided demo
programs. Make sure that you pick up your newly created Python by
making /usr/local/bin
dominant within your PATH
variable, and if you get display problems, set DISPLAY to your local
terminal:
$ cd ../Python-2.0/Demo/tkinter/matt $ PATH=/usr/local/bin:$PATH $ export PATH $ DISPLAY=:0.0 $ export DISPLAY $ python slider-demo-1.py
You can see the results in Figure 3-11.
There are two main Win32 binary download alternatives for Python. The first set of binaries is available from the main Python portal’s FTP area:
http://www.python.org/ftp/ |
For example, one can be found at the following URL:
http://www.python.org/ftp/python/2.0/BeOpen-Python-2.0.exe |
These self-installing executables run smoothly under the usual Win32 Install Shield setup system. They also contain all the Tcl/Tk code necessary to run Tkinter for Python GUIs, should you choose to install it, without having to download this separately afterwards. There are other GUI techniques available to Python, such as wxWindows covered later in this chapter; however, we think Tkinter is a good one to get started with, especially for shorter programs and particularly since it’s so well documented.
There is also a Win32 version of Python available from ActiveState, similar in concept to ActivePerl (which we discussed in Chapter 2). You can download ActivePython (also based on Python 2.0) from this site:
http://www.activestate.com/Products/ActivePython/Download.html |
ActivePython also comes in Linux and Solaris flavors, and ActiveState promises that the following features will be available in the near future:
Database support
Further GUI toolkits
Further specialized packages as required
The database support sounds particularly interesting. If ActivePython eventually comes with DCOracle built in (saving us having to install from source ourselves), it could become an attractive Python platform. Installing Win32 ActivePython will require the Microsoft Windows installer (MSI), as we mentioned earlier for ActivePerl, which you can find here for either Windows NT or Windows 98 (further versions available will be listed on the download page):
http://www.ActiveState.com/download/contrib/Microsoft/NT/InstMsi.exe |
http://www.ActiveState.com/download/contrib/Microsoft/9x/InstMsi.exe |
Once you’ve installed MSI, you can download the ActivePython MSI file and double-click on it, as shown in Figure 3-12, to install ActivePython directly on your PC.
For
Tkinter to work, Build 202 of
ActivePython requires a separate installation of a specific binary
version of Tcl, tcl832.exe
, immediately
afterwards. This Tcl binary installer can be found at:
ftp://ftp.scriptics.com/pub/tcl/tcl8_3/ |
Now that we’ve set up our basic Python environment, let’s look at a simple Python GUI just to show you what’s possible. As we mentioned earlier, one of the most popular ways to rapidly prototype GUIs in Python is Tcl’s Tkinter interface.
In our continuing starship example, we currently have the power from Engineering and the Transporter Room has the requisite controls. The next thing we want to do is build a tricorder control for our trusty planet-bound starship medic. We’re about to beam down with him to the surface of “Planet Salaris.” Our doctor needs to try to locate all of those shape-shifting aliens that may be after the salt in our bodies. Our new Python GUI program will help in this life-and-death quest. Before we pick up the two doomed Redshirts from Security, the good doctor quickly programs his tricorder with the script shown in Example 3-6 to get it ready for the trip.
Example 3-6. The salaris.py File for Creating a Simple Tricorder Program
from Tkinter import * win = Frame( ) win.pack( ) Label(win, text='Tricorder').pack(side=TOP) Button(win, text='Beam Me Up').pack(side=TOP) saltLevel = Scale(win, label="SaltLevel
") saltLevel.pack(side=LEFT) alienLife = Scale(win, label="AlienLife
") alienLife.pack(side=LEFT) glowingRocks = Scale(win, label="GlowingRocks
") glowingRocks.pack(side=LEFT) win.mainloop( )
The most important entry in Example 3-6 is the import of the Tkinter extension on the first line. This gets us everything we need on the GUI front. Comparing this Python script with earlier ones written in Tcl and Perl, you may agree that the creation of our three sliding scale widgets within this short Python program appears somewhat cleaner than with our previous shipboard programs. This less cluttered Python approach may appear even more lucid when compared to the accompanying screen output in Figure 3-13 (started under Win32 by double-clicking it under Explorer). Python’s clarity can make its programs particularly easy to maintain. This characteristic is a real godsend in a multi-thousand-line system (or even in a twenty-line system!). Note how the highlighted code lines in Example 3-6 are faithfully reflected in the final GUI.
To allow Python applications to connect to Oracle databases, Digital Creations has created DCOracle, an open source extension that facilitates Oracle access from Python via the Oracle Call Interface (OCI), described in Chapter 2. Later on, we’ll combine DCOracle with Tkinter inside a simple GUI program, but for now we’ll just get it installed.
The main web site for DCOracle is:
http://www.zope.org/Products/DCOracle/ |
This Oracle database extension also follows the Python database API, which is covered at the following web page:
http://www.python.org/topics/database/modules.html |
DCOracle
is mostly written in Python, except for its
Buffer
and oci_
low-level
extension C modules. These particular DCOracle extensions contain a
comprehensive range of OCI-based calls to provide the foundation for
the functions listed in Tables Table 3-7, Table 3-8, Table 3-9, and Table 3-10.
Table 3-7. DCOracle Functions
Function |
Description |
---|---|
Connect |
Connects to the database via a string (user/password@system) |
close |
Closes the database connection down |
commit |
Commits pending transactions |
rollback |
Rolls back pending transactions |
cursor |
Creates a new cursor handle |
prepare |
Prepares supplied SQL for later execution |
callproc |
Calls a named body of PL/SQL with bound parameters as required |
getSource |
Brings back source code for the given PL/SQL object name |
objects |
Returns basic information on user objects |
Table 3-8. DCOracle Cursor Object Functions
Function |
Description |
---|---|
close |
Closes the cursor |
execute |
Executes the supplied SQL operation |
fetchone |
Fetches the next row of cursor information |
fetchmany |
Fetches the next set of rows |
fetchall |
Fetches all remaining rows of a query |
Table 3-9. DCOracle Handle and DBI Helper Object Functions
Function |
Description |
---|---|
execute |
Executes a database operation that has already been prepared |
dbiDate |
Constructs a date in the Python database API format |
dbiRaw |
Holds a raw binary value |
Table 3-10. DCOracle Extensions to the Python Database API
Function |
Description |
---|---|
procedures |
Allows the manipulation of PL/SQL |
length |
Returns a Large Object (LOB) length |
read |
Reads data from a LOB |
write |
Writes data to a LOB |
At present there are no compilation instructions with the download for Win32, though we’re sure these will soon follow.
To compile DCOracle under Unix and attach it to Python proper, follow these steps:
Download the source code for DCOracle from http://www.zope.org/Products/DCOracle/.
Unpack the latest stable download. If you need more information, see the extensive instructions accompanying the download (in our case, the latest download was 1.3.2).
Next, you’ll need to
compile the DCOracle extensions.
(Unfortunately, we have not yet found any binaries for the DCOracle
database package, though we’re confident these will appear for
Windows at some point. See the latest README
files for up-to-date information.) First, though, move to where
you’ll later compile the DCOracle extensions:
$ cd DCOracle-1.3.2/src
Here you’ll find various setup files, such as these:
Setup-7.3.2
|
Setup-8.0.4
|
Setup-8.0.4-solaris-intel
|
Setup-8.0.5-linux-intel
|
Setup-8.1.5
|
Pick whichever of these is most appropriate for your machine’s
version of Oracle (in our case, for Oracle 8.1.5,
Setup-8.1.5
) and copy it to a new
Setup
file, which the configuration process is
expecting to find when you run it later:
$ cp Setup-8.1.5 Setup
Now you need to prepare a Makefile. With the
download, you’ll receive a number of preinstallation
Makefiles. Choose whichever one of these you
want, based upon your version of Python. Because we were using Python
2.0, we chose the latest pre-installation
Makefile, which in our case turned out to be
Makefile.pre.in-1.5
. Perform these two steps to
create the necessary Makefile:
$ cpMakefile.pre.in-1.5
Makefile.pre.in $ make -f Makefile.pre.in bootPYTHON=python
Notice PYTHON=python in the second line. This is
simply an instruction to let the later compilation process know that
our Python executable (available under
/usr/local/bin
) is actually called
“python”, as opposed to something like
“python20”.
We’re virtually there now, but as with other Oracle-accessing programs (like DBD::Oracle for Perl), DCOracle relies entirely on presupplied Oracle OCI code. You therefore need to make sure it knows where the Oracle OCI libraries are living:
$ ORACLE_HOME=/u01/app/oracle/product/8.1.5 $ export ORACLE_HOME $ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib:$ORACLE_HOME/lib $ export LD_LIBRARY_PATH
Now you can safely compile DCOracle with one simple build step:
$ make
Once you’re through the compilation, start up the target Oracle database and its listener, and you should receive the same output you received from the presupplied Python test program:
$ python DCOracle_test.py scott/tiger@orcl Import succeeded Connect succeeded
This means you can continue.
To complete the installation process, make sure that your DCOracle
extension is visible from the main
/usr/local/bin/python
program (this is not done
with a make install
command). To achieve this,
go to the main DCOracle-1.3.2
directory and copy
the two recently compiled extension files from the source compilation
directory to the main DCOracle
package
directory:
$ cd DCOracle-1.3.2 $ cp src/Buffer.so DCOracle $ cp src/oci_.so DCOracle
Now alter the previously unmentioned
PYTHONPATH
environment variable to ensure that Python can now find this new
package directory under its DCOracle-1.3.2
parental home:
$ PYTHONPATH=/myUnpackDir/DCOracle-1.3.2:$PYTHONPATH $ export PYTHONPATH
Python can now “see” the DCOracle package when it is referenced within a program.
We’ll build a very simple Python Tkinter GUI program (see Example 3-7) to demonstrate what’s possible with DCOracle. You might like to extend this example once you’ve examined the DCOracle functions listed earlier (which are all well-documented within the download files).
Example 3-7. The sql.py DCOracle and Tkinter Demo Program
from Tkinter import *
from DCOracle import *
class SQLTest(Frame): def printit(self): print "Employees" def createWidgets(self): self.employee = StringVar( ) self.employee.set("MILLER") self.radioframe = Frame(self) self.radioframe.pack( )dbc = Connect('scott/tiger')
c=dbc.cursor( )
c.execute('select ename from emp')
for row in c:
print row[0]
self.radioframe.choc = Radiobutton( self.radioframe,
text=row[0],
variable=self.employee,
value=row[0],
anchor=W )
self.radioframe.choc.pack(fill=X)
dbc.close( )
self.entry = Entry(self, textvariable=self.employee) self.entry.pack(fill=X) self.QUIT = Button( self, text='QUIT', foreground='blue', command=self.quit ) self.QUIT.pack(side=BOTTOM, fill=BOTH) def __init_ _(self, master=None): Frame.__init_ _(self, master) Pack.config(self) self.createWidgets( ) sqlExample = SQLTest( ) sqlExample.mainloop( )
The important part of this program is where we set up the
dbc
database connection before running into a
Python cursor loop to generate all the necessary radio buttons, one
per employee, via the myCursor
variable. You can
see the resulting output in Figure 3-14—a
visual feast, we think you’ll agree.
As we said earlier, we’re hoping those folks at ActiveState get to work quickly on ActivePython and add self-loading packages for Tkinter and DCOracle (on Linux, Solaris, and Windows) in a way that’s similar to what they’ve done to add Tk, Perl DBI, and DBD::Oracle for ActivePerl. If they do, Python may become simply irresistible.
Tk is an immense achievement, but your fairy godmother still has one sparkling wish left up her sleeve—wxPython. The wxPython project, led by Robin Dunn, may ultimately overtake Tkinter as the main windowing tool of choice among developers in the Python community. The wxPython system encapsulates the free wxWindows C++ framework. It has also been ported to both Linux and Unix via the GTK/Motif environment. Its main advantage for Python users is its freedom from a reliance on Tcl/Tk and its use of C++ GUI libraries fitting neatly into the object-oriented Python framework. For more on wxPython and wxWindows, check out the following web sites:
The main web site for wxPython, which includes binary downloads for Windows and RPMs for Linux.
For information on this emerging project combining Perl with wxWindows.
The wxDesigner home page; wxDesigner is a dialog editor and Rapid Application Development (RAD) tool for use with the wxWindows libraries.
The wxWindows site, for information on everything else connected with wxWindows (the C++-based foundation for creating GUI applications across a range of platforms). When you build wxPython from source on Unix, you will first need either a Motif or GTK+ wxWindows environment; full instructions exist on this site for creating either of these alternatives.
[26] The Red Hat Package Manager (RPM) is a popular mechanism used across most Linux distributions to install code packages such as Perl. You can find out much more about RPMs at http://rpm.redhat.com/RPM-HOWTO/index.html; see also Chapter 9, and Chapter 10.