Python 数据库应用

一、准备

    Mysql数据库 mysql安装教程

    pip工具安装  pip安装教程

    MySQLdb安装  (sudo pip install MySQLdb)

    mysql安装过程中,如果启动Mysqld失败,说明需要root权限.设置mysql密码,请参考设置mysql密码.如果发现不输入密码也能进入mysql交互界面,则说明user表中存在空的用户名,解决办法:mysql空用户

    如果MySQLdb版本不适合,可以在语句后加上==<版本号>


二、创建使用数据库

    python能够和大多数数据库进行操作。其中除了sqlite3内置,其余需要下载。下面主要介绍python和sqlite3以及mysql的操作.

#! /usr/bin/env python

import os
from random import randrange as rrange #导入随机模块

COLSIZ=10 #输出左对齐样式
RDBMSs={'s':'sqlite','m':'mysql'}
DB_EXC=None

def setup(): #返回sqlite或者mysql
    return RDBMSs[raw_input('''
        Choose a database system:
            
            (M)ySQL
            (S)QLite
        
        Enter choice:
    ''').strip().lower()[0]]

def connect(db,dbName):
    global DB_EXC
    dbDir='%s_%s' % (db,dbName) #自定义目录名称
    if db=='sqlite':#如果是选择sqlite数据库
        try:
            import sqlite3
        except ImportError,e:
            print 'database import error'
            return
        DB_EXC=sqlite3
        if not os.path.isdir(dbDir): #创建临时目录
            os.mkdir(dbDir)
        cxn=sqlite3.connect(os.path.join(dbDir,dbName))#连到这个临时目录上,因为sqlite没有默认的数据存储区域,因此自定义
    elif db=='mysql':#如果选择mysql数据库
        try:
            import  MySQLdb
            import  _mysql_exceptions as DB_EXC
        except ImportError,e:
            return None
        try:
            cxn=MySQLdb.connect(db=dbName)#如果已经连接了则选择数据库
        except DB_EXC.OperationalError,e:#还没有连接而出现的异常
            cxn=MySQLdb.connect(user='root',passwd='mysql12345')#进入原始连接,这里还可以加上db参数
        try:
            cxn.query('drop database %s' % dbName)#准备删除指定旧的数据库,因为后面要新建立这个数据库
        except DB_EXC.OperationalError, e:#如果要建立的数据库本身不存在
            pass
        cxn.query('create database %s' %dbName)#因为上面操作保证当前没有这个数据库
      #  cxn.query("grant all on %s.* to ''@'localhost'" % dbName)
        cxn.commit()
        cxn.close()
        cxn=MySQLdb.connect(db=dbName)#重新连接到刚才创建的数据库中
    else:
        return None
    return cxn#返回连接对象,该对象方法主要有close(),commit(),rollback(),cursor()

def create(cur):#进行创建表的操作
    try:
        cur.execute('''
            create table users ( login varchar(8),
                                            uid integer,
                                            prid integer)
                            ''')
    except DB_EXC.OperationalError,e:#创建失败,说明表已经存在了
                            #除了这个执行命令错误,还有警告异常Warning,错误异常Error,数据库接口错误异常InterfaceError,
                            #数据库错误异常DatabaseError,处理数据异常DataError,数据完整性错误异常IntegrityError,数据库内部异常
                            #InternalError,SQL执行失败异常ProgrammingError,执行不支持的特性异常NotSupportedError
        drop(cur)#因为表存在了因而先删除
        create(cur)#删除后再进行创建测试,这里可能出现一直循环的bug

drop=lambda cur:cur.execute('drop table users')#用于create函数失败时候调用的匿名函数

NAMES=(
    ('aaron',9312),('angela',7603),('dave',7306),
    ('davina',7902),('elliot',7911),('ernie',7410),
    ('jess',7912),('jim',7512),('larry',7311),
    ('leslie',7808),('melissa',8602),('pat',7711),
    ('serena',7003),('stan',7607),('faye',6812),
    ('amy',7209),
    )#要插入的数据

def randName():#随机生成器,每次随机从NAMES中拿出一个数据,同时保证了NAMES数据不变动,用pick作为临时操作对象
    pick=list(NAMES)
    while len(pick)>0:
        yield pick.pop(rrange(len(pick)))#随机取 ?1

def insert(cur,db):#插入数据
    if db=='sqlite':#如果是sqlite插入是qmark形式
        cur.executemany("insert into users values(?,?,?)",[(who,uid,rrange(1,5)) for who ,uid in randName()])
    elif db=='mysql':#如果是mysql插入是format形式
        cur.executemany("insert into users values(%s,%s,%s)",[(who,uid,rrange(1,5)) for who,uid in randName()])#插入模板

#getRC=lambda cur:hasattr(cur,'rowcount') and cur.rowcount or 0
getRC=lambda cur:cur.rowcount if hasattr(cur,'rowcount') else -1 #条件表达式来获取影响的行数 ?2

def update(cur):#更新数据
    fr=rrange(1,5)
    to=rrange(1,5)
    cur.execute("update users set prid=%d where prid=%d" % (to, fr))#将优先级为fr的变为to
    return fr,to,getRC(cur)

def delete(cur):#删除数据
    rm=rrange(1,5)
    cur.execute('delete from users where prid=%d' % rm) #将优先级为rm的删除
    return rm,getRC(cur)

def dbDump(cur):#打印出当前数据库中内容
    cur.execute("select * from users")
    print '\n%s%s%s' % ('LOGIN'.ljust(COLSIZ),'USERID'.ljust(COLSIZ),'PROJ#'.ljust(COLSIZ))#左对齐,大小为10
    for data in cur.fetchall():
        print '%s%s%s' % tuple([str(s).title().ljust(COLSIZ) for s in data])

def main():
    db=setup()#返回数据库类型,比如sqlite或者mysql
    print '*** Connecting to %r database' % db
    cxn=connect(db,'test')#连接到数据库,返回连接对象
    if not cxn:
        print 'ERROR: %r not supported, exiting' % db
        return
    cur=cxn.cursor()#获取游标对象,该对象主要方法arrysize每次取出fetchmany()多少条记录默认是1,lastrowid返回最后更新行的id,rowcount最后一次操作影响的行数
                #close(),excute(),executemany(),fetchone()获取结果集下一个,fetchmany([size=cursor.arraysize])获取结果集下几行,nextset()
                #指针移动到下一个结果集,next()用于迭代到下一行,rownumber当前结果集中游标的索引

    print '\n*** Creating users table'
    create(cur)#创建数据库

    print '\n*** Inserting names into tables'
    insert(cur,db)#向创建的数据库中插入数据
    dbDump(cur)#打印数据库中的内容

    print '\n*** Randomly moving floks',
    fr,to,num=update(cur)#更新数据库
    print 'from one proj (%d) to another (%d)' % (fr,to)
    print '\t(%d users moved)' % num
    dbDump(cur)#打印更新后的数据库内容

    print '\n*** Randomly choosing proj',
    rm,num=delete(cur)#删除数据
    print '(%d) to delete' % rm
    print '\t(%d users removed)' % num
    dbDump(cur)#打印删除后的内容

    print '\n*** Dropping users table'
    drop(cur)#删除表
    cur.close()
    cxn.commit()
    cxn.close()#关闭连接

if __name__=='__main__':
    main()

结果:

    Choose a database system:
            
            (M)ySQL
            (S)QLite
        
        Enter choice:
    s
*** Connecting to 'sqlite' database


*** Creating users table


*** Inserting names into tables


LOGIN     USERID    PROJ#     
Faye      6812      2         
Angela    7603      3         
Davina    7902      2         
Melissa   8602      4         
Elliot    7911      4         
Jim       7512      1         
Amy       7209      1         
Serena    7003      1         
Ernie     7410      2         
Jess      7912      1         
Dave      7306      3         
Leslie    7808      4         
Stan      7607      4         
Pat       7711      4         
Larry     7311      2         
Aaron     9312      2         


*** Randomly moving floks from one proj (2) to another (1)
	(5 users moved)


LOGIN     USERID    PROJ#     
Faye      6812      1         
Angela    7603      3         
Davina    7902      1         
Melissa   8602      4         
Elliot    7911      4         
Jim       7512      1         
Amy       7209      1         
Serena    7003      1         
Ernie     7410      1         
Jess      7912      1         
Dave      7306      3         
Leslie    7808      4         
Stan      7607      4         
Pat       7711      4         
Larry     7311      1         
Aaron     9312      1         


*** Randomly choosing proj (3) to delete
	(2 users removed)


LOGIN     USERID    PROJ#     
Faye      6812      1         
Davina    7902      1         
Melissa   8602      4         
Elliot    7911      4         
Jim       7512      1         
Amy       7209      1         
Serena    7003      1         
Ernie     7410      1         
Jess      7912      1         
Leslie    7808      4         
Stan      7607      4         
Pat       7711      4         
Larry     7311      1         
Aaron     9312      1         


*** Dropping users table

猜你喜欢

转载自blog.csdn.net/whitenigt/article/details/80139989