33. 数据库编程

发布时间 2023-09-17 19:12:27作者: 夏冰翎

一、数据库编程接口

  程序运行的时候,数据都是在内存中的。当程序终止的时候,通常都需要将数据保存到磁盘上。为了便于程序保存的读取数据,并能直接通过条件查询跨快速查询指定的数据,就出现了数据库(Database)这种专门用于集中存储和查询的软件。

  在 Python 中提供了数据库连接对象,它提供了获取数据库游标对象和提交/回滚事务的方法,以及如何关闭数据库连接。

【1】、获取连接对象

  我们可以使用 connect() 函数获取连接对象,该函数有多个参数,具体使用哪个参数,取决于使用的数据库类型。connect() 方法返回连接对象,这个对象表示目前和数据库的会话。连接对象支持的方法如下:

close()                                 # 关闭数据库连接
commit()                                # 提交当前事务
rollback()                              # 取消当前事务
cursor()                                # 使用该连接创建(并返回)一个游标对象

【2】、获取游标对象

  游标对象代表数据库中的游标,用于指示抓取数据操作的上下文。主要提供执行 SQL 语句、调用存储过程、获取查询结果等方法。我们可以通过使用连接对象的 cursor() 方法获取游标对象。

  游标对象的常用属性如下:

arraysize               # 使用fetchmany()方法时,一次取出的结果行数,默认为1
connection              # 创建此游标的连接
description             # 返回游标活动状态(7项元组):(name,type_code,display_size,internal_size,precision,scale,null_ok),只有name和type_code是必须的
lastrowid               # 上次修改行的ID,如果不支持行ID,则返回None
rowcount                # 上次execute()方法处理或影响的行数

  游标对象的常用方法如下:

callproc(procname[,parameters])         # 调用存储过程
close()                                 # 关闭游标
execute(operation[,parameters])         # 执行数据库查询或命令
executemany(operation,seq_of_params)    # 批量执行数据库查询或命令
fetchone()                              # 获取查询结果集的下一条记录
fetchmany(size)                         # 获取指定数量的记录
fetchall()                              # 获取结果集的所有记录
nextset()                               # 跳转下一个可用的结果集(如果支持)
setinputsizes(sizes)                    # 设置在调用execute()方法是分配的内存区域大小
setoutputsize(sizes)                    # 设置列缓冲区大小

二、使用SQLite数据库

  与许多其它数据库管理系统不同,SQLite 不是一个客户端/服务器结构的数据库引擎,而是一种嵌入式数据库,它的数据库就是一个文件。SQLite 将整个数据库,包括定义、表、索引以及数据本身,作为一个单独的、可跨平台使用的文件存储在主机中。

  由于 Python 中已经内置了 SQLite3,所以我们可以直接使用 import 语句导入 SQLite3 模块,无需安装任何其它的模块,可以直接使用。

import sqlite3

connection = sqlite3.connect("test.db")         # 获取连接
cursor = connection.cursor()                    # 获取游标

# 执行SQL语句,创建表
cursor.execute("create table if not exists user(name varchar(20), age int)")

# 向表中插入数据,新增用户信息
cursor.execute("insert into user(name,age) values('Sakura',10)")
cursor.execute("insert into user(name,age) values('Mikoto',14)")
cursor.execute("insert into user(name,age) values('Shana',15)")

# 执行查询结果
cursor.execute("select * from user")
# 获取查询结果
result = cursor.fetchone()                     # 使用fetchone()获取一条记录
print(result,end="\n\n")

result = cursor.fetchmany(2)                   # 使用fetchmany()获取多条记录
print(result,end="\n\n")

result = cursor.fetchall()                     # 使用fetchall()获取全部查询结果
print(result,end="\n\n")

# 修改用户信息
# 使用问号作为占位符代替具体的数值,然后使用一个元组来替代问号
# 使用占位符的方式可以避免SQL注入的风险
cursor.execute("update user set age = ? where name = ?",(12,"Sakura"))
cursor.execute("select * from user where name = ?",("Sakura",))
result = cursor.fetchall()
print(result,end="\n\n")

# 删除用户数据
cursor.execute("delete from user where name = ?",("Shana",))
cursor.execute("select * from user")
result = cursor.fetchall()
print(result,end="\n\n")

cursor.close()                                  # 关闭游标
connection.close()                              # 关闭数据库

三、使用MySQL数据库

  在 Python 中支持 MySQL 的数据库模块有很多,这里我们选择使用 PyMySQL。我们可以在 cmd 中使用 pip 命令安装:

pip intall PyMySQL
import pymysql

# 打开数据库连接
db = pymysql.connect(
    user="root",                                # 用户名
    password="abc123",                          # 密码
    host="localhost",                           # 主机地址
    port=3306,                                  # 端口号
    database="db_test",                         # 数据库名
)

# 使用cursor()方法创建一个游标对象cursor
cursor = db.cursor()

data = [
    ('Sakura',10),
    ('Mikoto',14),
    ('Shana',15),
]

try:
    # 使用execute()方法,执行SQL语句,创建表
    cursor.execute("create table if not exists user(name varchar(20), age int)")

    # 向表中插入数据,新增用户信息
    # 执行sql语句,插入多条记录
    # 不管字段是什么类型的,占位符统一是%s
    cursor.executemany("insert into user(name,age) values(%s,%s)",data)
    db.commit()                                 # 提交数据
except:
    db.rollback()                               # 发生错误时回滚

# 执行查询结果
cursor.execute("select * from user")
# 获取查询结果
result = cursor.fetchone()                      # 使用fetchone()获取一条记录
print(result,end="\n\n")

result = cursor.fetchmany(2)                    # 使用fetchmany()获取多条记录
print(result,end="\n\n")

result = cursor.fetchall()                      # 使用fetchall()获取全部查询结果
print(result,end="\n\n")

# 修改用户信息
# 使用问号作为占位符代替具体的数值,然后使用一个元组来替代问号
# 使用占位符的方式可以避免SQL注入的风险
try:
    cursor.execute("update user set age = %s where name = %s",(12,"Sakura"))
    db.commit()
except:
    db.rollback()

cursor.execute("select * from user where name = %s",("Sakura",))
result = cursor.fetchall()
print(result,end="\n\n")

# 删除用户数据
try:
    cursor.execute("delete from user where name = %s","Shana")
    db.commit()
except:
    db.rollback()

cursor.execute("select * from user")
result = cursor.fetchall()
print(result,end="\n\n")

cursor.close()                                  # 关闭游标
db.close()                                      # 关闭数据库连接