In contrast to PHP, which copies html directly to output, python
scripts are true programs, which must print all the output. In
addition, Apache doesn't "know" this, so by default would just send out
the python code, not what you want.
#!/usr/bin/python
# -*- coding: utf-8 -*-
print "Content-Type: text/html; charset=UTF-8" # ALWAYS this header (HTML is following)
#--that takes care of charset!
# more headers, such as Set-Cookie:
print # blank line, end of headers
print """<!DOCTYPE HTML>
<html lang="en">
<head>
<title>Python demonstration</title>
<!-- all the head information you want here -->
</head>
<body>"""
This module is imported, and provides storage for the form data,
which is an object with "methods" from which one may get the data
coming from a form
import cgi"sports" may appearseveral times in the query string, in which case form.getvalue('sports') will return a list. But if only one sport is selected, it would return a simple value instead. getlist returns a list of one element in this case. Note that awkward names like "sports[]" are not needed.
form=cgi.FieldStorage()
who = form.getvalue('who') # we expect certain fields to be there, value may be None if field is left blank
names = form.keys() # all the input names for which values exist
sports = form.getlist('sports') # which might be a <select multiple name="sports">
import psycopg2Values go in and out of the database as strings, here we needed to convert price to a float, since it is going to be used numerically. See the python tutorial at www.python.org for the distinction between tuple, list, and dictionary, represented with (), [], and {} respectively.
try:
con=psycopg2.connect('dbname=fruitstand host=localhost user=mickey password=MoUsE')
except:
print "Database connect trouble"
import sys
sys.exit()
curs=con.cursor() # extra object that manages query execution
# get a dictionary of prices
curs.execute("select trim(name), price from fruit where stock>0")
prices={}
for f,p in curs.fetchall(): # loop through all the rows
prices[f]=float(p)
A transaction in SQL is considered an atomic operaction, it either
completes without error, or is "rolled back" leaving the database
unchanged. In psql, each statement (and anything invoked by its rules)
is considered an atomic transaction. We have seen one fail: Ordering a
large number of bananas causes the inventory to be updated, and that
fails if the result would be negative, causing the ordre to fail. What
should happen with the res of the order. PHP would go ahead, after
perhaps printing an error message, this is referred to as "autocommit."
Python takes the opposite view, regarding the whole program as a
single all-or-nothing transaction. this can be altered in two ways. We
can set autocommit on the connection, or issue explicit commit or
rollback instructions to the connection
(after the cursor has
processed a statement that might fail. Responsibilities are divided
here between the two objects.) Here is an example from fruitorder.py:
try: # insert might fail if not enough stock
curs.execute("insert into sold values (%s,%s)", (fruit,qty)) # like pg_query_params
price=prices[fruit] # look up in a dict!
print "<tr><td>%s</td><td>%d</td><td>%.2f</td><td>%.2f</td> </tr>" %\ #continuation line
(fruit, qty, price, qty*price) #insert values at the %'s
sum += qty*price
con.commit() # make this permanent
except:
con.rollback() #acknowledge failure, reset connection to allow further queries
print "<tr><td>%s</td><td colspan=3>Sorry, we don't have %d</td></tr>" %\
(fruit, qty)
[jensen@lindgren ~]$ pythonTo get help on any "object" type help(l) for example, to find out what you can do with the list l
>>> t=(2,4,8) # I type
>>> t[1]
4 # system response
>>> t[1]=44
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> l=[2,4,8]
>>> l[1]=44
>>> l
[2, 44, 8]
>>> l=l+[7,77,'hello']
>>> l
[2, 44, 8, 7, 77, 'hello']
>>> l.pop(2)
8
>>> l
[2, 44, 7, 77, 'hello']
>>> quit
Use quit() or Ctrl-D (i.e. EOF) to exit
>>> quit()
[jensen@lindgren ~]$