程序访问数据库服务


点击这里,看视频讲解,学习下面内容

前面,我们都是通过命令行客户端对数据库进行操作的。

这个命令行客户端 是一个特殊的 数据库客户端程序, 它能够把我们的SQL语句发送给 MySQL数据库服务,然后把运行结果展示在屏幕上。

大部分的数据库客户端程序,是要完成特殊的功能的。 典型的就是我们后面要学习的 web服务端程序。

我们后面的教程会教大家开发一个 医药公司的 订单管理系统 BYCRM。

这个系统要完成各种业务功能,比如 药品的添加、客户的添加、订单的创建等等,当然要大量地使用数据库服务,它也是一个数据库客户端程序。

我们现在先学习一下 自己开发简单的程序,来使用数据库服务。

我们的应用程序要访问数据库,其实是访问数据服务进程,这个数据服务进程再去读写磁盘上的数据文件。

我们的应用 通常需要调用一个客户端库,也就是下图中的驱动模块, 通过网络访问数据库服务。

白月黑羽Python3教程


安装客户端库


点击这里,看视频讲解,学习下面内容

目前使用Python语言访问mysql数据库, 推荐使用客户端库 mysqlclientPyMySQL

PyMySQL 是纯Python实现的。

而 mysqlclient 库是C语言开发的,性能相对高一些。

这两个库都遵循 Python统一数据库访问接口规范(参考PEP 249


既然是Python的第三方库,当然是用 pip安装了。

运行命令 pip install mysqlclient 安装 mysqlclient,


如果你想使用 的客户端库是 PyMySQL ,运行命令 pip install PyMySQL 安装

读取数据库表内容


点击这里,看视频讲解,学习下面内容


点击这里,看视频讲解,学习下面内容


我们来看下面这样的一个使用 mysqlclient 库读取数据库表的例子。

import MySQLdb

# 创建一个 Connection 对象,代表了一个数据库连接
connection = MySQLdb.connect(
                host="192.168.0.100",# 数据库IP地址  
                user="username",     #  mysql用户名
                passwd="xxxxx",      # mysql用户登录密码
                db="dbname" ,        # 数据库名
                # 如果数据库里面的文本是utf8编码的,
                #charset指定是utf8
                charset = "utf8")   

# 返回一个 Cursor对象
c = connection.cursor()

# 执行一个获取 users 表中所有记录的 sql 语句
c.execute("""SELECT * FROM users """)


# rowcount属性记录了最近一次 execute 方法获取的数据行数
numrows = c.rowcount

for x in range(numrows):
    # fetchone 方法返回的是一个元组,
    # 代表获取的一行记录,元组里面每个元素代表一个字段
    row = c.fetchone()
    print(row)

如果你使用 的客户端库是 PyMySQL,只有前面 导入库和连接数据库服务 的代码略有差别,像这样


import pymysql

# 创建一个 Connection 对象,代表了一个数据库连接
connection = pymysql.connect(
                host="192.168.0.100", 
                user="username",        
                password="xxxxx",      # mysql用户登录密码
                database="dbname" ,    # 数据库名
                charset = "utf8")   

通常也就是 password、 database 两个参数不太一样,其它常规参数都一样。

后面的代码和使用mysqlclient的代码都是一样的。


我们可以发现,对数据库的操作是 通过SQL语句 进行的。

我们的代码需要先创建一个 Connection 对象 , 然后再通过Connection 对象创建一个Cursor 对象。

最后使用Cursor对象的execute方法,传入要数据库服务执行的SQL语句。

调用execute执行完SQL语句后,cursor 对象的 fetchone 方法是获取一行记录。

fetchone 方法返回的是一个元组,代表获取的一行记录,元组里面每个元素代表一个字段。

上面的代码通过一个for循环,可以依次获取到数据库的记录行。


我们还可以用 fetchmany 方法来获取多行记录,该方法的参数就是要获取记录的条数,比如

# 执行一个获取 users 表中所有记录的 sql 语句
c.execute("""SELECT * FROM users """)

# fetchmany方法返回的是一个元组,
# 里面每个元素也是元组,代表一行记录
rows = c.fetchmany(2)
print(rows)

我们还可以用 fetchall 方法来获取所有记录,比如

# 执行一个获取 users 表中所有记录的 sql 语句
c.execute("""SELECT * FROM users """)

# fetchall方法返回的是一个元组,
# 里面每个元素也是元组,代表一行记录
rows = c.fetchall()
print(rows)

插入数据到数据库表


点击这里,看视频讲解,学习下面内容

我们来看下面这样的一个插入数据到数据库表的例子。

import MySQLdb

# 创建一个Connection 对象,代表了一个数据库连接
connection = MySQLdb.connect(
                host="192.168.0.100",# 数据库IP地址  
                user="username",     #  mysql用户名
                passwd="xxxxx",      # mysql用户登录密码
                db="dbname" ,        # 数据库名
                # 如果数据库里面的文本是utf8编码的,
                #charset指定是utf8
                charset = "utf8")   

# 返回一个cursor对象
c = connection.cursor()



#  插入一行数据到 user 表中
c.execute(f"INSERT INTO users ( name, nickname, phone) VALUES ('baiyueheiyu', '白月黑羽', '13312345678')")

# 注意 一定要commit,否则添加数据不生效
connection.commit()

connection.close()

插入数据操作当然也是通过 Cursor对象的execute方法,传入要数据库服务执行的 插入操作对应的SQL语句

注意, 凡是执行 更改 数据的SQL语句,包括:插入、修改、删除, 后面一定要调用connection的commit方法,否则不生效。

获得插入行自增字段值

通过前面的学习,我们知道,通常数据库表会设计一个名为 id 的主键字段, 这个字段类型通常是 AUTO_INCREMENT

执行插入语句时,我们不知道这个id 值是多少,这是由数据库自动增长的。

但是我们的程序有时需要知道 插入成功后的id值。因为后面的SQL语句可能会用到这个id。

这时可以通过 cursor对象的 lastrowid 属性获取。

如果执行了 INSERT 语句 插入数据到数据库表,并且该表有 AUTO_INCREMENT 字段, cursor对象的lastrowid 就会保存自增的字段值

示例如下

#  插入一行数据到 user 表中,该表有id字段为 AUTO_INCREMENT 类型
c.execute(f"INSERT INTO users ( name, nickname, phone) VALUES ('baiyueheiyu', '白月黑羽', '13312345678')")

# 打印出AUTO_INCREMENT字段id的值
print(c.lastrowid)

lastrowid 的具体信息参考官方文档这里

SQL语句中使用变量

Python程序执行SQL语句,经常需要把一些变量值 填入SQL语句。

很自然的想法的是:直接使用Python的字符串格式化, 比如

# 查询使用变量
name = input('请输入查询姓名')
c.execute(f"SELECT * FROM users WHERE username='{name}'")

# 插入使用变量
info = input('请输入登录名、姓名、电话,以+隔开')
username,realname,phone = info.split('+')
c.execute(f"""INSERT INTO users  (name, nickname, phone) 
VALUES ('{username}', '{realname}', '{phone}')""")

# 注意 一定要commit,否则添加数据不生效
connection.commit()



当然可以。

但是如果你的Python程序是网站服务,这些参数是前端传递过来的,这种做法不是很推荐,有被 SQL 注入攻击 的危险。

可以使用参数化方式,如下

# 查询使用变量
name = input('请输入查询姓名')
c.execute(f"SELECT * FROM users WHERE username=%s", (name,))

# 插入使用变量
info = input('请输入登录名、姓名、电话,以+隔开')
username,realname,phone = info.split('+')
c.execute(f"""INSERT INTO users  (name, nickname, phone) 
VALUES (%s, %s, %s)""" , (username,realname,phone))

注意: Python MySQL 语句参数化, 所有占位符写法 都是 %s ,不管这个参数是 字符串类型 还是数字类型、日期类型等等。

除了使用 %s 占位,还可以有其他方式,具体参考这里

您需要高效学习,找工作? 点击咨询 报名实战班

点击查看学员就业情况

作业和练习

前面的作业,我们创建了Prac库,在其中添加user 表 和 medicine表,并且添加了一些记录。

请用 Python语言编写一个程序 连接数据库,执行下面的操作

  • 在user表中查询 注册日期在 2019年1月2日之后的 用户记录,并且查询结果安装注册日期升序排列,注册日期相同再根据 等级 降序排列。

  • 用SQL语句 修改 medicine 表,将其中 有效期截止时间 在 2019年1月2日之前的药品 有效状态 改为 0

  • 用SQL语句 删除 medicine 表中, 有效期截止时间 在 2019年1月2日之前的药品

上一页
下一页