极简python之数据库sqlite

时启发 2024-05-22 20:11:22

相对于将字典数据存储到文件,为了进一步提高数据访问效率,使用现成的数据库进行操作是必然的趋势。在说明python如何操作数据库之前,需要我们从Oracle、Sql server、MySql、dbm、Redis、sqlite等数据库中,选择一种与业务逻辑大小和复杂程度相匹配的数据库。对于初学者而言,选择关系型数据库MySql和sqlite是合适的。由于sqlite不需要专门搭建数据库服务器,可仅以文件的形式在本地存在,这对我们解释基本的数据库操作和了解Sql语句有所帮助。因此,本文选用了sqlite数据库。

还需要讲明白的一点是,关系型数据库与键值型数据库的不同之处,键值型数据库直接将字典对象的键值对逐一存储下来即可。关系型数据库更像是一张表格(table),每一行对应字典对象的值,字典对象的关键字,存储在表格的表头部位,需要提前定义,这通常用create table这条sql语句来实现。

这里,我们将用一个简单的通讯录程序来说明python的数据库操作。这里不妨假设,我们需要保存每个联系人的(姓名、性别、年龄、联系地址、联系电话)等信息,并保存在tongxunlu数据库(关于数据库创建的sql语句,不妨参阅mysql的相关说明)的contacts表中,使得每个联系人的信息都像这样的一个字典对象:

图1 联系人信息的范例

由于需要先行定义“表头”(也即关键字的类型、长度等信息的说明),所以,我们需要首先创建一个存放联系人数据的数据表contacts,这个操作只需且仅需一次。sqlite数据库操作的sql语句是这样的,见图2:

图2 联系人contacts数据表的定义

需要注意的是,为了将来数据删除、更新操作方便,除最初需要的几个信息外,我们为每一个联系人信息(或者换称之为行、记录等),额外定义了id和time_created数据(或者列、字段等)。id列的作用是为每一个联系人定义了一个唯一值,该值为整型,且由数据库系统自行执行自增操作(比如表中最大的id值为5,增加新的数据时,新增的数据的id应该为6);time_created列的作用是为了记录我们添加此联系人的时间,以便将来扩展功能用,新增联系人时,该列的默认值为新增那一刻的时间。这也说明,即便是最简单的需求和实际实现之间肯定也是存在差异的。python初始化数据库及数据表contacts的实现,编写在init_db函数中,见图3:

图3 初始化数据库并创建数据表contacts

除了引入sqlite3模块并使用它的connect等函数,以及从pathlib模块中引入Path类外,其他并没有什么新鲜内容。sqlite3.connect函数,作用是连接到参数所指数据库(文件),如果对应的本地文件不存在,将尝试新建一个指定文件名的文件。而execute的作用即执行指定的单个sql语句,而后续的数据的增加、删除、修改,都可以通过此函数执行对应的sql语句来完成。先来定义add_contact函数,添加数据,见图4:

图4 添加联系人信息的函数add_contact

注意,sqlite数据库execute方法调用时,提供了额外的参数,这是因为在组合sql串时,为了防止语句注入带来的风险(比如在输入中输入了单引号'),使用了命名占位符的功能,图中

sql=f"insert into contacts ({','.join(keys)}) values({','.join([(':'+key)forkeyinkeys])})",组合的结果等同于:

sql = 'insert into contacts(name,sex,age,address,phone) value(:name,:sex,:age,:address,:phone)'

其中,由于字典键值存储位置不确定的原因,name,sex,age,address,phone的顺序可能不太一致。执行完成后,新加行的id值可以通过调用cursor的lastrowid获得。

我们连续调用了5次add_contact添加了5个联系人(见图5),并通过数据库查询工具(我采用的是免费开源的DbGate)查看并验证添加后的结果(见图6):

图5 调用add_contact

图6 通过数据库管理工具验证添加完成后的数据

0 阅读:45

时启发

简介:读书笔记,编程经验,旅途见闻,人生感悟