用Python进行SQLite数据库操作

 

 

简单的介绍

      SQLite数据库是一款非常小巧的嵌入式开源数据库软件,也就是说没有独立的维护进程,所有的维护都来自于程序本身。它是遵守ACID的关联式数据库管理系统,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源世界著名的数据库管理系统来讲,它的处理速度比他们都快。SQLite第一个Alpha版本诞生于2000年5月. 至今已经有10个年头,SQLite也迎来了一个版本 SQLite 3已经发布。

 

基本介绍:

 1.导入Python SQLITE数据库模块

     Python2.5之后,内置了SQLite3,成为了内置模块,这给我们省了安装的功夫,只需导入即可~

import sqlite3

 

2. 创建/打开数据库 

     在调用connect函数的时候,指定库名称,如果指定的数据库存在就直接打开这个数据库,如果不存在就新创建一个再打开。

cx = sqlite3.connect("E:/test.db")
     也可以创建数据库在内存中。
con = sqlite3.connect(":memory:")

 

3.数据库连接对象

    打开数据库时返回的对象cx就是一个数据库连接对象,它可以有以下操作:

  1. commit()--事务提交   
  2. rollback()--事务回滚   
  3. close()--关闭一个数据库连接   
  4. cursor()--创建一个游标

    关于commit(),如果isolation_level隔离级别默认,那么每次对数据库的操作,都需要使用该命令,你也可以设置isolation_level=None,这样就变为自动提交模式。

 

4.使用游标查询数据库 

    我们需要使用游标对象SQL语句查询数据库,获得查询对象。 通过以下方法来定义一个游标。

cu=cx.cursor()

 

     游标对象有以下的操作:
  1. execute()--执行sql语句   
  2. executemany--执行多条sql语句   
  3. close()--关闭游标   
  4. fetchone()--从结果中取一条记录,并将游标指向下一条记录   
  5. fetchmany()--从结果中取多条记录   
  6. fetchall()--从结果中取出所有记录   
  7. scroll()--游标滚动  

具体操作:

1. 建表

cu.execute("create table catalog (id integer primary key,pid integer,name varchar(10) UNIQUE,nickname text NULL)")

 

上面语句创建了一个叫catalog的表,它有一个主键id,一个pid,和一个name,name是不可以重复的,以及一个nickname默认为NULL。

 

2. 插入数据 

请注意避免以下写法:

# Never do this -- insecure 会导致注入攻击

pid=200
c.execute("... where pid = '%s'" % pid)
正确的做法如下,如果t只是单个数值,也要采用t=(n,)的形式,因为元组是不可变的。 
for t in[(0,10,'abc','Yu'),(1,20,'cba','Xu')]:
    cx.execute("insert into catalog values (?,?,?,?)", t)
简单的插入两行数据,不过需要提醒的是,只有提交了之后,才能生效.我们使用数据库连接对象cx来进行提交commit和回滚rollback操作.
cx.commit()

3.查询

cu.execute("select * from catalog") 

要提取查询到的数据,使用游标的fetch函数,如:

In [10]: cu.fetchall()
Out[10]: [(0, 10, u'abc', u'Yu'), (1, 20, u'cba', u'Xu')]

如果我们使用cu.fetchone(),则首先返回列表中的第一项,再次使用,则返回第二项,依次下去.

 

4.修改

In [12]: cu.execute("update catalog set name='Boy' where id = 0")
In [13]: cx.commit()

注意,修改数据以后提交

5.删除

cu.execute("delete from catalog where id = 1")  
cx.commit() 

代码实现进行测试:

#coding=utf-8
'''
Created on 2015年4月24日
@author: gsr03
'''
import sqlite3
import os
'''SQLite数据库是一款非常小巧的嵌入式开源数据库软件,也就是说
没有独立的维护进程,所有的维护都来自于程序本身。
在python中,使用sqlite3创建数据库的连接,当我们指定的数据库文件不存在的时候
连接对象会自动创建数据库文件;如果数据库文件已经存在,则连接对象不会再创建
数据库文件,而是直接打开该数据库文件。
    连接对象可以是硬盘上面的数据库文件,也可以是建立在内存中的,在内存中的数据库
    执行完任何操作后,都不需要提交事务的(commit)

    创建在硬盘上面: conn = sqlite3.connect('c:\\test\\test.db')
    创建在内存上面: conn = sqlite3.connect('"memory:')

    下面我们一硬盘上面创建数据库文件为例来具体说明:
    conn = sqlite3.connect('c:\\test\\hongten.db')
    其中conn对象是数据库链接对象,而对于数据库链接对象来说,具有以下操作:

        commit()            --事务提交
        rollback()          --事务回滚
        close()             --关闭一个数据库链接
        cursor()            --创建一个游标

    cu = conn.cursor()
    这样我们就创建了一个游标对象:cu
    在sqlite3中,所有sql语句的执行都要在游标对象的参与下完成
    对于游标对象cu,具有以下具体操作:

        execute()           --执行一条sql语句
        executemany()       --执行多条sql语句
        close()             --游标关闭
        fetchone()          --从结果中取出一条记录
        fetchmany()         --从结果中取出多条记录
        fetchall()          --从结果中取出所有记录
        scroll()            --游标滚动

'''

#global var
#数据库文件绝句路径
DB_FILE_PATH = ''
#表名称
TABLE_NAME = ''
#是否打印sql
SHOW_SQL = True

def get_conn(path):
    '''获取到数据库的连接对象,参数为数据库文件的绝对路径
    如果传递的参数是存在,并且是文件,那么就返回硬盘上面改
    路径下的数据库文件的连接对象;否则,返回内存中的数据接
    连接对象'''
    conn = sqlite3.connect(path)
    conn.text_factory=str
    if os.path.exists(path) and os.path.isfile(path):
        print('硬盘上面:[{}]'.format(path))
        return conn
    else:
        conn = None
        print('内存上面:[:memory:]')
        return sqlite3.connect(':memory:')

def get_cursor(conn):
    '''该方法是获取数据库的游标对象,参数为数据库的连接对象
    如果数据库的连接对象不为None,则返回数据库连接对象所创
    建的游标对象;否则返回一个游标对象,该对象是内存中数据
    库连接对象所创建的游标对象'''
    if conn is not None:
        return conn.cursor()
    else:
        return get_conn('').cursor()

###############################################################
####            创建|删除表操作     START
###############################################################
def drop_table(conn, table):
    '''如果表存在,则删除表,如果表中存在数据的时候,使用该
    方法的时候要慎用!'''
    if table is not None and table != '':
        sql = 'DROP TABLE IF EXISTS ' + table
        if SHOW_SQL:
            print('执行sql:[{}]'.format(sql))
        cu = get_cursor(conn)
        cu.execute(sql)
        conn.commit()
        print('删除数据库表[{}]成功!'.format(table))
        close_all(conn, cu)
    else:
        print('the [{}] is empty or equal None!'.format(sql))

def create_table(conn, sql):
    '''创建数据库表:student'''
    if sql is not None and sql != '':
        cu = get_cursor(conn)
        if SHOW_SQL:
            print('执行sql:[{}]'.format(sql))
        cu.execute(sql)
        conn.commit()
        print('创建数据库表[student]成功!')
        close_all(conn, cu)
    else:
        print('the [{}] is empty or equal None!'.format(sql))

###############################################################
####            创建|删除表操作     END
###############################################################

def close_all(conn, cu):
    '''关闭数据库游标对象和数据库连接对象'''
    try:
        if cu is not None:
            cu.close()
    finally:
        if cu is not None:
            cu.close()

###############################################################
####            数据库操作CRUD     START
###############################################################

def save(conn, sql, data):
    '''插入数据'''
    if sql is not None and sql != '':
        if data is not None:
            cu = get_cursor(conn)
            for d in data:
                if SHOW_SQL:
                    print('执行sql:[{}],参数:[{}]'.format(sql, d))
                cu.execute(sql, d)
                conn.commit()
            close_all(conn, cu)
    else:
        print('the [{}] is empty or equal None!'.format(sql))

def fetchall(conn, sql):
    '''查询所有数据'''
    if sql is not None and sql != '':
        cu = get_cursor(conn)
        if SHOW_SQL:
            print('执行sql:[{}]'.format(sql))
        cu.execute(sql)
        r = cu.fetchall()
        if len(r) > 0:
            for e in range(len(r)):
                print(r[e])
    else:
        print('the [{}] is empty or equal None!'.format(sql)) 

def fetchone(conn, sql, data):
    '''查询一条数据'''
    if sql is not None and sql != '':
        if data is not None:
            #Do this instead
            d = (data,) 
            cu = get_cursor(conn)
            if SHOW_SQL:
                print('执行sql:[{}],参数:[{}]'.format(sql, data))
            cu.execute(sql, d)
            r = cu.fetchall()
            if len(r) > 0:
                for e in range(len(r)):
                    print(r[e])
        else:
            print('the [{}] equal None!'.format(data))
    else:
        print('the [{}] is empty or equal None!'.format(sql))

def update(conn, sql, data):
    '''更新数据'''
    if sql is not None and sql != '':
        if data is not None:
            cu = get_cursor(conn)
            for d in data:
                if SHOW_SQL:
                    print('执行sql:[{}],参数:[{}]'.format(sql, d))
                cu.execute(sql, d)
                conn.commit()
            close_all(conn, cu)
    else:
        print('the [{}] is empty or equal None!'.format(sql))

def delete(conn, sql, data):
    '''删除数据'''
    if sql is not None and sql != '':
        if data is not None:
            cu = get_cursor(conn)
            for d in data:
                if SHOW_SQL:
                    print('执行sql:[{}],参数:[{}]'.format(sql, d))
                cu.execute(sql, d)
                conn.commit()
            close_all(conn, cu)
    else:
        print('the [{}] is empty or equal None!'.format(sql))
###############################################################
####            数据库操作CRUD     END
###############################################################


###############################################################
####            测试操作     START
###############################################################
def drop_table_test():
    '''删除数据库表测试'''
    print('删除数据库表测试...')
    conn = get_conn(DB_FILE_PATH)
    drop_table(conn, TABLE_NAME)

def create_table_test():
    '''创建数据库表测试'''
    print('创建数据库表测试...')
    create_table_sql = '''CREATE TABLE `student` (
                          `id` int(11) NOT NULL,
                          `name` varchar(20) NOT NULL,
                          `gender` varchar(4) DEFAULT NULL,
                          `age` int(11) DEFAULT NULL,
                          `address` varchar(200) DEFAULT NULL,
                          `phone` varchar(20) DEFAULT NULL,
                           PRIMARY KEY (`id`)
                        )'''
    conn = get_conn(DB_FILE_PATH)
    create_table(conn, create_table_sql)

def save_test():
    '''保存数据测试...'''
    print('保存数据测试...')
    save_sql = '''INSERT INTO student values (?, ?, ?, ?, ?, ?)'''
    data = [(1, 'Hongten', '男', 20, '广东省广州市', '13423****62'),
            (2, 'Tom', '男', 22, '美国旧金山', '15423****63'),
            (3, 'Jake', '女', 18, '广东省广州市', '18823****87'),
            (4, 'Cate', '女', 21, '广东省广州市', '14323****32')]
    conn = get_conn(DB_FILE_PATH)
    save(conn, save_sql, data)

def fetchall_test():
    '''查询所有数据...'''
    print('查询所有数据...')
    fetchall_sql = '''SELECT * FROM student'''
    conn = get_conn(DB_FILE_PATH)
    fetchall(conn, fetchall_sql)

def fetchone_test():
    '''查询一条数据...'''
    print('查询一条数据...')
    fetchone_sql = 'SELECT * FROM student WHERE ID = ? '
    data = 1
    conn = get_conn(DB_FILE_PATH)
    fetchone(conn, fetchone_sql, data)

def update_test():
    '''更新数据...'''
    print('更新数据...')
    update_sql = 'UPDATE student SET name = ? WHERE ID = ? '
    data = [('HongtenAA', 1),
            ('HongtenBB', 2),
            ('HongtenCC', 3),
            ('HongtenDD', 4)]
    conn = get_conn(DB_FILE_PATH)
    update(conn, update_sql, data)

def delete_test():
    '''删除数据...'''
    print('删除数据...')
    delete_sql = 'DELETE FROM student WHERE NAME = ? AND ID = ? '
    data = [('HongtenAA', 1),
            ('HongtenCC', 3)]
    conn = get_conn(DB_FILE_PATH)
    delete(conn, delete_sql, data)

###############################################################
####            测试操作     END
###############################################################

def init():
    '''初始化方法'''
    #数据库文件绝句路径
    global DB_FILE_PATH
    DB_FILE_PATH = 'c:\\test\\hongten.db'
    #数据库表名称
    global TABLE_NAME
    TABLE_NAME = 'student'
    #是否打印sql
    global SHOW_SQL
    SHOW_SQL = True
    print('show_sql : {}'.format(SHOW_SQL))
    #如果存在数据库表,则删除表
    drop_table_test()
    #创建数据库表student
    create_table_test()
    #向数据库表中插入数据
    save_test()
    

def main():
    init()
    fetchall_test()
    print('#' * 50)
    fetchone_test()
    print('#' * 50)
    update_test()
    fetchall_test()
    print('#' * 50)
    delete_test()
    fetchall_test()

if __name__ == '__main__':
    main()

使用上面代码进行实现对功能测试

中间有两个问题

1.对中文添加编码设定

#coding=utf-8

2.对sqllite插入非text类型不能使用utf8,会报错

在getconn方法中添加 conn.text_factory=str

具体为什么还是很明白

 

参考博客:

http://www.cnblogs.com/yuxc/archive/2011/08/18/2143606.html

http://www.cnblogs.com/hongten/p/hongten_python_sqlite3.html

 

 

 

 

 

 

 

 
posted @ 2015-04-24 14:35  水滴石穿100  阅读(682)  评论(0编辑  收藏  举报