Python/FAQ/Доступ к базам данных

Материал из Wiki.crossplatform.ru

Перейти к: навигация, поиск
· Python ·

Содержание

[править] Introduction

# See http://www.python.org/doc/topics/database/ for Database Interfaces details.
# currently listed on http://www.python.org/doc/topics/database/modules/
#
#  DB/2, Informix, Interbase, Ingres, JDBC, MySQL, pyodbc, mxODBC, ODBC Interface,
 
#  DCOracle, DCOracle2, PyGresQL, psycopg, PySQLite, sapdbapi, Sybase, ThinkSQL.
#

[править] Making and Using a DBM File

#-------------------------------------
import anydbm
filename = "test.db"
try:
    db = anydbm.open(filename)
except anydbm, err:
    print "Can't open %s: %s!" % (filename, err)
 
db["key"] = "value"        # put value into database
 
if "key" in db:            # check whether in database
    val = db.pop("key")    # retrieve and remove from database
db.close()                 # close the database
 
#-------------------------------------
# download the following standalone program
#!/usr/bin/python
# userstats - generates statistics on who logged in.
# call with an argument to display totals
 
import sys, os, anydbm, re
 
db_file = '/tmp/userstats.db'       # where data is kept between runs
 
 
try:
    db = anydbm.open(db_file,'c')   # open, create if it does not exist
except:
    print "Can't open db %s: %s!" % (db_file, sys.exc_info()[1])
    sys.exit(1)
 
 
if len(sys.argv) > 1:
    if sys.argv[1] == 'ALL':
        userlist = db.keys()
    else:
        userlist = sys.argv[1:]
    userlist.sort()
    for user in userlist:
        if db.has_key(user):
            print "%s\t%s" % (user, db[user])
        else:
 
            print "%s\t%s" % (user, 0)
else:
    who = os.popen('who').readlines()  # run who(1)
    if len(who)<1:
        print "error running who"       # exit
 
        sys.exit(1)
    # extract username (first thin on the line) and update
    user_re = re.compile("^(\S+)")
    for line in who:
        fnd = user_re.search(line)
        if not fnd:
            print "Bad line from who: %s" % line
            sys.exit(1)
        user = fnd.groups()[0]
        if not db.has_key(user):
            db[user] = "0"
 
        db[user] = str(int(db[user])+1) # only strings are allowed
db.close()

[править] Emptying a DBM File

# Emptying a DBM File
 
import anydbm
 
try:
    db = anydbm.open(FILENAME,'w')   # open, for writing
 
except anydbm.error, err:
    print "Can't open db %s: %s!" % (filename, err)
    raise SystemExit(1)
 
db.clear()
db.close()
# -------------------------------
try:
    db = anydbm.open(filename,'n')   # open, always create a new empty db
 
except anydbm.error, err:
    print "Can't open db %s: %s!" % (filename, err)
    raise SystemExit(1)
 
db.close()
# -------------------------------
import os
 
try:
    os.remove(FILENAME)
except OSError, err:
    print "Couldn't remove %s to empty the database: %s!" % (FILENAME,
        err)
    raise SystemExit
 
try:
    db = anydbm.open(FILENAME,'n')   # open, flways create a new empty db
except anydbm.error, err:
    print "Couldn't create %s database: %s!" % (FILENAME, err)
    raise SystemExit

[править] Converting Between DBM Files

# Converting Between DBM Files
 
 
# download the following standalone program
#!/usr/bin/python
# db2gdbm: converts DB to GDBM
 
import sys
import dbm, gdbm
 
if len(sys.argv)<3:
    print "usage: db2gdbm infile outfile"
 
    sys.exit(1)
 
(infile, outfile) = sys.argv[1:]
 
# open the files
try:
    db_in = dbm.open(infile)
except:
    print "Can't open infile %s: %s!" % (infile, sys.exc_info()[1])
    sys.exit(1)
try:
 
    db_out = dbm.open(outfile,"n")
except:
    print "Can't open outfile %s: %s!" % (outfile, sys.exc_info()[1])
    sys.exit(1)
 
# copy (don't use db_out = db_in because it's slow on big databases)
# is this also so for python ?
for k in db_in.keys():
    db_out[k] = db_in[k]
 
 
# these close happen automatically at program exit
db_out.close()
db_in.close()

[править] Merging DBM Files

OUTPUT.update(INPUT1)
OUTPUT.update(INPUT2)
 
OUTPUT = anydbm.open("OUT","n")
for INPUT in (INPUT1, INPUT2, INPUT1):
    for key, value in INPUT.iteritems():
        if OUTPUT.has_key(key):
            # decide which value to use and set OUTPUT[key] if necessary
 
            print "key %s already present: %s, new: %s" % (
                    key, OUTPUT[key], value )
        else:
            OUTPUT[key] = value

[править] Locking DBM Files

# On systems where the Berkeley DB supports it, dbhash takes an
# "l" flag:
import dbhash
dbhash.open("mydb.db", "cl") # 'c': create if doesn't exist
 
 
# @@INCOMPLETE@@

[править] Sorting Large DBM Files

# @@INCOMPLETE@@
# @@INCOMPLETE@@

[править] Treating a Text File as a Database Array

# @@INCOMPLETE@@
# @@INCOMPLETE@@

[править] Storing Complex Data in a DBM File

# shelve uses anydbm to access and chooses between DBMs.
# anydbm detect file formats automatically.
 
import shelve
db = shelve.open("celebrities.db")
 
name1 = "Greg Stein"
name2 = "Greg Ward"
 
# shelve uses pickle to convert objects into strings and back.
# This is automatic.
db[name1] = ["of ViewCVS fame", "gstein@lyra.org"]
db[name2] = ["of Distutils fame", "gward@python.net"]
 
greg1 = db[name1]
greg2 = db[name2]
 
 
print "Two Gregs: %x %x" % (id(greg1), id(greg2))
 
if greg1 == greg2:
    print "You're having runtime fun with one Greg made two."
else:
 
    print "No two Gregs are ever alike."
 
# Changes to mutable entries are not written back by default.
# You can get the copy, change it, and put it back.
entry = db[name1]
entry[0] = "of Subversion fame"
db[name1] = entry
 
# Or you can open shelve with writeback option. Then you can
# change mutable entries directly. (New in 2.3)
 
db = shelve.open("celebrities.db", writeback=True)
db[name2][0] = "of Optik fame"
 
# However, writeback option can consume vast amounts of memory
# to do its magic. You can clear cache with sync().
db.sync()
#-----------------------------

[править] Persistent Data

# DON'T DO THIS.
 
import os as _os, shelve as _shelve
 
_fname = "persist.db"
if not _os.path.exists(_fname):
    var1 = "foo"
    var2 = "bar"
 
_d = _shelve.open("persist.db")
globals().update(_d)
 
print "var1 is %s; var2 is %s"%(var1, var2)
var1 = raw_input("New var1: ")
var2 = raw_input("New var2: ")
 
 
for key, val in globals().items():
    if not key.startswith("_"):
        _d[key] = val
# @@INCOMPLETE@@

[править] Executing an SQL Command Using DBI and DBD

#-----------------------------
 
import dbmodule
 
dbconn = dbmodule.connect(arguments...)
 
cursor = dbconn.cursor()
cursor.execute(sql)
 
while True:
   row = cursor.fetchone()
   if row is None:
       break
   ...
 
cursor.close()
dbconn.close()
 
 
#-----------------------------
import MySQLdb
import pwd
 
dbconn = MySQLdb.connect(db='dbname', host='mysqlserver.domain.com',
                        port=3306, user='user', passwd='password')
 
cursor = dbconn.cursor()
cursor.execute("CREATE TABLE users (uid INT, login CHAR(8))")
 
 
# Note: some databases use %s for parameters, some use ? or other
# formats
sql_fmt = "INSERT INTO users VALUES( %s, %s )"
 
for userent in pwd.getpwall():
   # the second argument contains a list of parameters which will
   # be quoted before being put in the query
 
   cursor.execute(sql_fmt, (userent.pw_uid, userent.pw_name))
 
cursor.execute("SELECT * FROM users WHERE uid < 50")
 
for row in cursor.fetchall():
   # NULL will be displayed as None
   print ", ".join(map(str, row))
 
cursor.execute("DROP TABLE users")
cursor.close()
dbconn.close()
 
#-----------------------------

[править] Program: ggh - Grep Netscape Global History

# @@INCOMPLETE@@
# @@INCOMPLETE@@