【Python进阶】正则表达式、pymysql模块

目录

一、正则表达式的概述

1、基本介绍

2、快速使用re模块

二、正则的常见规则

1、匹配单个字符

2、原始字符串

3、匹配多个字符

4、匹配开头和结尾

5、匹配分组

三、Python与MySQL交互

1、pymysql模块的安装

2、pymysql的操作步骤

3、connection对象

4、cursor对象

四、数据记录操作

1、准备数据表

2、插入数据

3、修改数据

4、删除数据

5、SQL注入

6、语句参数化

7、查询数据

五、注册与登录案例

1、注册

2、登录

一、正则表达式的概述

1、基本介绍

正则表达式,也叫做规则表达式,通常会说成【正则】。

实际上,正则表达式就是指符合一定规则的字符串,同时它能用于检查一段文本数据是否与某种模式匹配。

比如,在网站注册新用户时,对用户名、手机号等的验证就使用了正则表达式。

在Python中,有一个专门用于处理正则表达式的模块:

# 导入模块
import re

在正则表达式中,可以使用单个字符或一段字符串来匹配满足正则规则的文本数据。而我们要学习的,就是正则规则。

在一些文本编辑器中,可以使用正则表达式来查找或替换一些文本。

总结:

(1)正则表达式就是一段具有特殊含义的字符串,即正则表达式 == 字符串;

(2)注意:在Python中,若要操作正则表达式,要使用re模块。

2、快速使用re模块

我们已经知道,可以使用re模块来操作正则表达式。

re模块常用方法:

函数名含义
match(pattern, string)返回一个已匹配成功的对象。其中,参数pattern表示正则字符串,参数string表示要匹配的内容。

当成功匹配数据后,结果存放在对象的函数:

函数名含义
group(num=0)匹配成功的内容,num默认是0,表示匹配的所有数据结果。

例如,一起来完成:

(1)使用正则快速验证手机号码是否合格;

(2)验证手机是否合格的条件有:手机号码以1开头且总位数为11位,全部为数字且不包含其他字符;

(3)根据要求,使用re模块完成对手机号码的验证。

import re
​
str1 = '13812345678'
regex_str = '1[3456789][0-9]{9}'  # 这种写法没有定义开头结尾限定,只要包含匹配的内容就行
regex_str = '^1[3456789][0-9]{9}$'  # 这种写法佳乐开头结尾限定,必须精准匹配才行
​
result = re.match(regex_str,str1)  # 判断str1这个字符串是否符合regex_str这个正则规则
if result is not None:
    print('字符串内容符合正则!')
    print(result.group())  # group 表示只获取字符串中匹配上的部分
else:
    print('字符串内容不符合正则!')
​

总结:

(1)如果要使用re模块来匹配数据,应该使用re模块的match()匹配方法;

(2)注意:当使用re模块未匹配到对应的数据时,会返回None。

二、正则的常见规则

1、匹配单个字符

常用的匹配单个字符的语法:

代码功能
.匹配除\n之外的任何单个字符。
[ ]匹配[ ]中列举的字符。
\d匹配一个数字字符,比如[0-9]。
\D匹配一个非数字字符,比如[^0-9]
\s匹配任何空白字符。(空格、tab、换行)
\S匹配任何非空白字符。
\w匹配非特殊字符,比如a-z、A-Z、0-9、_、汉字。
\W匹配特殊字符,比如非字母、非数字、非汉字等。

例如,一起来完成:

(1)使用.来匹配任意单个字符;

(2)使用[a-z]、[A-Z]、[^0-9]分别来查看小写字母、大写字母、非数字;

(3)使用\d来匹配一个数字字符;

(4)使用\w来匹配一个可能有数字、大小写字母、下划线的单个字符。

# 1.导入模块
import re
​
# 报错:正则有误;  能输出结果,表示正常
# print(f"结果:{xxx}")
​
# 2.任意字符
 print(f"结果:{re.match('.','h').group()}")
 print(f"结果:{re.match('.','1').group()}")
 print(f"结果:{re.match('.','_').group()}")
 print(f"结果:{re.match('.','python').group()}")
​
# 3.小写、大写、非数字
 print(f"结果:{re.match('[a-z]','a').group()}")
 print(f"结果:{re.match('[a-z]','y').group()}")
 print(f"结果:{re.match('[a-z]','Z').group()}")   # 报错
 print(f"结果:{re.match('[a-z]','abc').group()}")
 print(f"结果:{re.match('[A-Z]','B').group()}")
 print(f"结果:{re.match('[0-9]','1').group()}")
 print(f"结果:{re.match('[^0-9]','b').group()}")
 print(re.match('\D','b').group())
​
# 4.一个数字
 print(f"结果:{re.match('[0-9]','8').group()}")
 print(f"结果:{re.match('[0-9]','66').group()}")
 print(re.match('\d','6').group())
 5.单字符
 print(re.match('\w','6').group())
 print(re.match('\w','a').group())
 print(re.match('\w','N').group())
 print(re.match('\w','_').group())
 print(re.match('\w','深圳').group())

2、原始字符串

原始字符串指的是:在所有的正则表达式前,最好加上r,语法:

r"正则表达式"

例如,一起来完成:

(1)请使用正则来匹配路径名:E:\\

(2)请尝试使用不同方式去匹配数据,观察效果;

(3)思考:当要定义一段批量文本内容时,该怎么定义字符串?

print('E:\a.txt')    # 这里 会把 \a 当成一个字符, \是转义字符
print('E:\\a.txt')   # \\ 合成 一个  \
print(r'E:\a.txt')   # 前边加 r 表示 字符串中的任何字符没有特殊函数,就是普通字符串,不要过度解读

总结:

(1)当不想给一段文本数据内容转义而又要表达原始意义时,可以在文本数据内容前添加r。

(2)注意:当正确写了正则后又匹配不出数据结果时,可以试试在正则前添加r解决问题。

3、匹配多个字符

常用的匹配多个字符的语法:

代码功能
X*匹配X出现0次或无限次,即可有可无。
X+匹配X出现1次或无限次,即至少有1次。
X?匹配X出现1次或0次,即有一次或一次也没有。
X{m}匹配X恰好出现m次。
X{m,n}匹配X至少m次,但是不超过n次。

例如,一起来完成:

(1)使用X*来匹配出一个字符串:第1个字母为大小写字母,后面都是小写字母且这些字母可有可无;

(2)通过X+来匹配一个具有数字、大小写字母、下划线的字符串;

(3)通过X?来匹配0到99之间的任意数字;

(4)通过X{n,m}匹配出5到16位的密码,可以是大小写英文字母、数字、下划线。

import re
​
 result = re.match("","").group()
 print(f"结果:{result}")
# X*
 result = re.match("[a-zA-Z]","x").group()
 result = re.match("[a-zA-Z]","U").group()
 result = re.match("[a-zA-Z][a-z]*","U").group()
 result = re.match("[a-zA-Z][a-z]*","UzogY").group()
 print(f"结果:{result}")
# X+
 result = re.match("\w","123abcABC_hello").group()
 result = re.match("\w+","123abcABC_hello").group()
 print(f"结果:{result}")
# X?    0-9    10-99
 result = re.match("[1-9][0-9]","12").group()
 result = re.match("[1-9][0-9]","98").group()
 result = re.match("[1-9]?[0-9]","0").group()
 result = re.match("[1-9]?[0-9]","17").group()
 # result = re.match("[1-9]?[0-9]","09").group()
 print(f"结果:{result}")
# X{m,n}
result = re.match("[a-zA-Z0-9_]{5,16}","123456").group()
result = re.match("[a-zA-Z0-9_]{5,16}","1234fjwoefwoe23__fwjelf").group()   # ?如何解决?  $
print(f"结果:{result}")

==总结:==

(1)使用匹配多个字符的方式,可以一个字符或批量数据内容;

(2)注意:当要匹配批量数据内容时,应该优先使用:*。

4、匹配开头和结尾

代码功能
^匹配字符串开头。
$匹配字符串结尾。

例如,一起来完成:

(1)使用^来匹配非数字的单个字符;

(2)使用$来匹配www.baidu.com的结尾处。

import re

# result = re.match("","").group()
# print(f"结果:{result}")


# 匹配开头: 非数字
result = re.match("[0-9]","1aaa1").group()    # 默认是从第一个字符开始匹配,如果第一个字符不是数字就结束
print(f"结果:{result}")

result = re.match("[^0-9]","g").group()    # 默认是从第一个字符开始匹配
print(f"结果:{result}")

result = re.match("[^0-9]","heima").group()  # 默认是从第一个字符开始匹配
print(f"结果:{result}")

result = re.match("[^0-9]+","heima").group()  # 默认是从第一个字符开始匹配
print(f"结果:{result}")

print('----------------------')
# 匹配结尾
result = re.match(".+","www.baidu.com").group()
print(f"结果:{result}")

result = re.match("www.baidu.com","www.baidu.com").group()
print(f"结果:{result}")

result = re.match("www.baidu.com$","www.baidu.com.cn.gov.edu").group()  # 是否以某个串结尾
print(f"结果:{result}")

result = re.match("^www.baidu.com$","www.baidu.com").group()
print(f"结果:{result}")

总结:

(1)当要限定结尾处内容时,可以使用$符号。

5、匹配分组

要获取分组数据信息,语法:

代码功能
X|Y匹配X或Y的任意一个表达式。
(X)将括号中字符X作为一个分组用于获取,且从1开始统计分组。

例如,一起来完成:

(1)使用X|Y来匹配出0-100之间的所有数字字符结果;

(2)使用(X)来匹配出含有163、126、qq这几个内容且用户名位数为4-12位的邮箱,如itcast@163.com等。

import re

result = re.match("","").group()
print(f"结果:{result}")

0-100
result = re.match("hello|world","world").group()  # 只要hello和world有一个匹配上即可
print(f"结果:{result}")

result = re.match("[1-9]?[0-9]|100","8").group()
print(f"结果:{result}")

result = re.match("[1-9]?[0-9]|100","87").group()
print(f"结果:{result}")

result = re.match("[1-9]?[0-9]|100","99").group()
print(f"结果:{result}")

result = re.match("[1-9]?[0-9]|100","100").group()  # 10
print(f"结果:{result}")

result = re.match("100|[1-9]?[0-9]","100").group()
print(f"结果:{result}")

result = re.match("100|[1-9]?[0-9]","10").group()
print(f"结果:{result}")
print('----------------------------------------')
# 邮箱号
result = re.match("(\w{4,12})@(126|163|qq).(com|cn)","hellopy@qq.com").group()
print(result)
print(f"结果:{result[:result.find('@')]}")


       #  re.match('xxxx(表达式1)xxxx(表达式2)',字符串).group(1)
       # group(2) 里边的数字表示获取第2个括号中的内容
result = re.match("(\w{4,12})@(126|163|qq).com","hellopy@163.com").group(2)
print(result)
print(f"结果:{result[:result.find('@')]}")


result = re.match("(\w{4,12})@(126|163|qq).com","hellopy@163.com").group(1)
print(f"结果:{result[:result.find('@')]}")

result = re.match("(\w{4,12})@(126|163|qq).com","hellopy@163.com").group(2)
print(f"结果:{result[:result.find('@')]}")

# group 中不加数字,返回匹配的所有内容
result = re.match("(\w{4,12})@(126|163|qq).com","hellopy@qq.com").group()
print(result)
print(f"结果:{result[:result.find('@')]}")

总结:

(1)如果在涉及到要获取分组数据时,一定记得要使用()来写正则;

(2)注意:要获取分组数据时,在正则中的()从1开始计算分组,比如获取第1组,则group()的括号中应该填写1。

三、Python与MySQL交互

1、pymysql模块的安装

当要使用Python和MySQL数据库进行交互,需要借助一个第三方模块:pymysql。

在使用pymysql模块前,先进行安装:

pip install pymysql

有时使用pip install xxx命令安装时较慢,若要提升pip下载的速度,可采用命令:

pip install 模块名 [-i 镜像源地址]
pip install pymysql -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install pymysql -i http://mirrors.aliyun.com/pypi/simple/

比如,在国内的镜像源中,有很多可供使用的源地址:

镜像来源镜像源地址
豆瓣http://pypi.douban.com/simple/
阿里云Simple Index
清华大学Simple Index
中国科技大学Simple Index
华中理工大学http://pypi.hustunique.com/
山东理工大学http://pypi.sdutlinux.org/

当成功安装pymysql模块后,可直接导入使用:

# 导入模块
import pymysql

例如,一起来完成:

(1)在Python中,使用命令安装pymysql模块;

(2)当成功安装模块后,即可导入并验证是否已成功安装;

(3)思考:还有其他方式安装模块吗?

总结:

(1)当要在Python中安装pymysql模块,可以使用pip install pymsql命令;

(2)注意:当要使用pymysql模块时,可以直接导入使用,语法:import pymysql。

2、pymysql的操作步骤

在Python中,使用pymysql模块来操作MySQL数据的基本步骤:

对于图解,操作步骤说明:

(1)导入模块;

(2)创建连接对象;

(3)创建游标对象;

(4)使用游标对象执行SQL并进行增删改查;

(5)关闭游标对象;

(6)关闭连接对象。

例如,一起来了解:

(1)操作pymysql模块的基本步骤;

(2)对各个步骤做详细说明。

(1)导入模块;
	导入模块前, 优先安装pymysql模块: pip install pymysql
	import pymysql
	# 使用模块操作MySQL数据库
----------------------------------
(2)创建连接对象;
	db_conn = pymysql.connect()
		# 用户名 root
		# 密码 123456
		# IP地址 127.0.0.1    localhost
		# 端口号 3306
		# 数据库名 班级名_db_xxx
		# 编码格式 utf8   gbk
----------------------------------
(3)创建游标对象;
	db_cursor = db_conn.cursor()
		# 游标获取数据
----------------------------------
(4)使用游标对象执行SQL并进行增删改查;
	db_cursor.execute(xxxx)
		# 增 insert into 表名[(字段1, 字段2, ...)] values(值1, 值2,...)[,(值1, 值2,...),...][;]
		# 删 delete from 表名 [where 条件];
		# 改 update 表名 set 字段1=值1[, 字段2=值2, ...] [where 条件];
		# 查 select *[字段1, 字段2, ...] from 表名 [where 条件];
----------------------------------
(5)关闭游标对象;
	close()
----------------------------------
(6)关闭连接对象。
	close()

总结:

(1)当操作完pymysql后,需要对连接、游标等对象资源进行关闭,可以使用close()方法;

(2)注意:为了便于使用和操作pymysql模块,建议按照操作步骤来进行处理。

3、connection对象

我们都知道,在使用MySQL数据库前,首先需要登录并进行连接。[命令行、DataGrip]

类似地,在使用pymysql模块时,也需要登录并进行连接,且此时需要使用connection对象。

connection是用于建立与数据库的连接,需要使用pymysql模块来调用:

函数含义
connect(host=None, port=0, user=None, password="", database=None, charset='',...)用于创建Connection连接对象。 ①host:表示连接MySQL的IP地址。若为本机,则可表示成'localhost'或'127.0.0.1';若为其他计算机,则表示为具体IP地址; ②port:表示连接的MySQL的端口号,默认是3306; ③user:表示连接的用户名,默认是root; ④password:表示连接的密码; ⑤database:表示数据库的名称; ⑥charset:表示采用的编码方式,设定为'utf8'即可。

当成功通过connect()获取并得到连接对象后,常用函数:

函数含义
commit()用于事务提交,在进行数据操作时需要进行事务提交后才会生效。
close()用于关闭连接。
cursor()用于返回cursor对象,可使用该对象来执行SQL语句并获取结果。

说明:

(1)使用pymysql模块时,已默认开启了事务,因此要让数据操作生效,则必须要进行事务提交;

(2)为了节约系统内存资源,通常在使用完Connection连接对象后,要进行close()关闭连接。

总结:

(1)通常情况下,使用pymysql连接MySQL数据库,需要知道:IP地址、端口号、用户名、密码;

(2)注意:pymysql模块操作MySQL是默认已经开启了事务。

4、cursor对象

若要执行SQL语句时,则需要使用cursor对象,可通过connection对象的cursor()方法进行创建。

函数含义
cursor()用于返回cursor对象,可使用该对象来执行SQL语句并获取结果。

当有了cursor对象后,常用函数:

函数含义
execute(operate [, param])用于执行SQL语句,返回受影响的行数。 其中,参数operate为字符串类型,表示SQL语句; 参数parameters为列表类型,表示SQL语句中的参数。
fetchone()在执行查询语句时,获取查询结果集的第一行数据,返回一个元组,即(v1, v2,...)。
fetchall()在执行查询时,获取结果集的所有行,返回一个元组,即((v11, v12,...), (v21, v22,...),...)。
close()关闭cursor对象。

说明:

(1)使用execute()执行SQL语句时,SQL语句应写成字符串型;

(2)当关闭connection和cursor对象时,记得先关闭cursor游标,后关闭connection连接。

总结:

(1)当要使用cursor游标对象来执行SQL语句时,可以使用excute()方法;

(2)注意:在使用pymysql执行SQL语句时,要使用cursor对象来操作。

四、数据记录操作

1、准备数据表

通常情况下,在使用pymysql模块前,会先创建好数据库和数据表字段信息。

这样,可以更便于后期操作。

例如,使用MySQL命令完成:

(1)创建一个班级db_students数据库,并设定为utf8编码;

(2)在库中新建一个数据表,包含编号id、姓名name、性别gender、年龄age等字段;

(3)其中,字段编号id为整型、主键且自动增长;

(4)操作完成后,查看表结构,并查看表内是否有数据内容。

######################新建库和表#############################
# 创建库
create database if not exists db_students charset utf8;
# 使用库
use db_students;
# 查看表信息
show tables;
# 创建表
create table if not exists student(
    id int primary key auto_increment,
    name varchar(20),
    gender varchar(10),
    age int
) engine = InnoDB default charset utf8;
# 查看表字段
desc student;
# 查看表数据
select * from student;

总结:

(1)在操作pymysql前,请记得先创建好数据表,便于后面的程序执行。

2、插入数据

当已成功创建好了数据库和数据表,就可以使用pymysql来给表内添加数据了。使用函数:

函数含义
execute(operate [, param])用于执行SQL语句,返回受影响的行数。 其中,参数operate为字符串类型,表示SQL语句; 参数parameters为列表类型,表示SQL语句中的参数。

说明:

param参数是可选项。

例如,使用pymysql模块来完成:

(1)使用execute()向学生表中插入1条学生数据;

(2)使用DataGrip查看添加成功后的数据结果;

(3)思考:如果要插入两条数据,该怎么做呢?

# 1、导入模块
import pymysql

# 2、创建连接对象
conn = pymysql.connect(
    host='192.168.88.100',
    port=3306,
    user='root',
    password='123456',
    database= 'db_students',
    charset='utf8'
)
print(conn)  # 测试一下服务器是否联通

# 3、获取游标
db_cursor = conn.cursor()

# 4、使用游标来执行sql
result = db_cursor.execute("insert into student(name,gender,age) values ('刘备','男',23)")
print(result) # 返回影响的行数

# 5、增删改之后,一定要让操作生效,必须要提交事务,否则不生效
conn.commit()

# 6、关闭游标对象;
db_cursor.close()

# 7、关闭连接对象。
conn.close()

总结:

(1)当使用pymysql模块插入数据,必须使用commit()方法提交事务;

(2)注意:使用PyCharm编写程序插入数据成功后,可以到DataGrip中查看是否已成功添加数据。

3、修改数据

当数据显示有误时,就需要来修改数据内容。使用函数:

函数含义
execute(operate [, param])用于执行SQL语句,返回受影响的行数。 其中,参数operate为字符串类型,表示SQL语句; 参数parameters为列表类型,表示SQL语句中的参数。

说明:

param参数是可选项。

例如,使用pymysql模块来完成:

(1)使用execute()修改学生表中id为1的数据,并把年龄修改为19岁,姓名修改为王军;

(2)使用DataGrip查看修改成功后的数据结果;

(3)思考:能否把性别为男的所有数据,性别都修改为Male呢?
 

# 1、导入模块
import pymysql

# 2、创建连接对象
conn = pymysql.connect(
    host='192.168.88.100',
    port=3306,
    user='root',
    password='123456',
    database= 'db_students',
    charset='utf8'
)
print(conn)  # 测试一下服务器是否联通

# 3、获取游标
db_cursor = conn.cursor()

# 4、使用游标来执行sql
result = db_cursor.execute("""
    update student set name = '大乔' where id = 4
    """)
print(result) # 返回影响的行数

# 5、增删改之后,一定要让操作生效,必须要提交事务,否则不生效
conn.commit()

# 6、关闭游标对象;
db_cursor.close()

# 7、关闭连接对象。
conn.close()

总结:

(1)当使用pymysql模块修改数据,要使用commit()方法进行提交事务;

(2)注意:若要修改数据表的数据内容,必须先已存在该数据。

4、删除数据

当数据内容已失效时,就需要来删除数据内容。使用函数:

函数含义
execute(operate [, param])用于执行SQL语句,返回受影响的行数。 其中,参数operate为字符串类型,表示SQL语句; 参数parameters为列表类型,表示SQL语句中的参数。

说明:

param参数是可选项。

例如,使用pymysql模块来完成:

(1)使用execute()删除学生表中id为2的这条数据;

(2)使用DataGrip查看删除成功后的数据结果;

(3)思考:目前,使用execute()操作数据时,都采用硬编码方式,会存在什么问题吗?

# 1、导入模块
import pymysql

# 2、创建连接对象
conn = pymysql.connect(
    host='192.168.88.100',
    port=3306,
    user='root',
    password='123456',
    database= 'db_students',
    charset='utf8'
)
print(conn)  # 测试一下服务器是否联通

# 3、获取游标
db_cursor = conn.cursor()

# 4、使用游标来执行sql
result = db_cursor.execute("""
    delete from student where name = '曹操'
    """)
print(result) # 返回影响的行数

# 5、增删改之后,一定要让操作生效,必须要提交事务,否则不生效
conn.commit()

# 6、关闭游标对象;
db_cursor.close()

# 7、关闭连接对象。
conn.close()

总结:

(1)当要删除数据记录时,应该使用delete关键字;

(2)注意:使用pymysql模块删除数据时,也需要进行提交事务。

5、SQL注入

SQL注入指的是:恶意篡改或注入SQL条件。

当开发者的数据条件若被恶意篡改,那就达不到预期的查询效果。

为了了解SQL注入是怎么回事?通过一个案例来分析。

例如,使用命令来完成:

(1)给学生表tb_student中添加一些数据,查看效果;

(2)查询age=22的这条数据的所有信息;

(3)使用SQL注入方式来恶意篡改查询条件,比如在条件结尾处,添加or 1=1,并查询结果;

(4)思考:对比两次查询结果,该如何解决这类SQL注入问题呢?

# 1、导入模块
import pymysql

# 2、创建连接对象
conn = pymysql.connect(
    host='192.168.88.100',
    port=3306,
    user='root',
    password='123456',
    database= 'db_students',
    charset='utf8'
)
print(conn)  # 测试一下服务器是否联通

# 3、获取游标
db_cursor = conn.cursor()

input_id = input('请输入你要删除的id:')  # 从键盘输入: 88 or 1=1
# 4、使用游标来执行sql                   # 发现所有数据都被删除,因为or后边的条件永远成立,条件永远为真
result = db_cursor.execute(f"""
    delete from student where id = {input_id}   
    """)
print(result) # 返回影响的行数

# 5、增删改之后,一定要让操作生效,必须要提交事务,否则不生效
conn.commit()

# 6、关闭游标对象;
db_cursor.close()

# 7、关闭连接对象。
conn.close()

注意:当恶意篡改了SQL条件后,查询的结果可能达不到预期效果。

6、语句参数化

如果要解决SQL注入的问题,在pymysql模块中,可采用语句参数化来解决。

语句参数化是指以%s表示值,然后再传入具体的参数值进行替换。

为了更好理解语句参数化,可以把SQL语句的参数化、值,简要地理解为print()函数中的格式化符号输出:

print("xxx%s, xxx%d"%(name, age))

要使用cursor对象的函数:

函数含义
execute(operate, param)用于执行SQL语句,返回受影响的行数。 其中,参数operation为字符串类型,表示具体的SQL语句,注意,若在SQL语句中要向外传入参数值,则该参数均使用%s表示; 参数parameters为列表类型,表示SQL语句中的参数。

说明:

param参数的类型是列表list。

例如,使用pymysql模块来完成:

(1)通过键盘录入的方式输入变化的数据值;

(2)使用语句参数化和execute()给数据表添加一条数据内容;

(3)操作完成后,使用DataGrip查看添加成功后的数据结果。

# 1、导入模块
import pymysql

# 2、创建连接对象
conn = pymysql.connect(
    host='192.168.88.100',
    port=3306,
    user='root',
    password='123456',
    database= 'db_students',
    charset='utf8'
)
print(conn)  # 测试一下服务器是否联通

# 3、获取游标
db_cursor = conn.cursor()

input_id = input('请输入你要删除的id:')  # 从键盘输入: 88 or 1=1
params = [input_id]
# 不管你从键盘输入什么都会当做普通字符串赋值给%s,id = '88 or 1=1'  -以前--> id = 88 or 1=1
sql= "delete from student where id =  %s "  
# 4、使用游标来执行sql                  
result = db_cursor.execute(sql,params)

print(result) # 返回影响的行数

# 5、增删改之后,一定要让操作生效,必须要提交事务,否则不生效
conn.commit()

# 6、关闭游标对象;
db_cursor.close()

# 7、关闭连接对象。
conn.close()
# 1、导入模块
import pymysql

# 2、创建连接对象
conn = pymysql.connect(
    host='192.168.88.100',
    port=3306,
    user='root',
    password='123456',
    database= 'db_students',
    charset='utf8'
)
print(conn)  # 测试一下服务器是否联通

# 3、获取游标
db_cursor = conn.cursor()

param = ['张飞','男',33]
sql = 'insert into student(name,gender,age) values (%s,%s,%s)'
result = db_cursor.execute(sql, param)


print(result) # 返回影响的行数

# 5、增删改之后,一定要让操作生效,必须要提交事务,否则不生效
conn.commit()

# 6、关闭游标对象;
db_cursor.close()

# 7、关闭连接对象。
conn.close()

总结:

(1)语句参数化时,必须使用%s表示参数

(2)注意:要进行语句参数化时,使用execute()方法时需要传递两个参数。

7、查询数据

查询数据,要使用cursor对象的函数:

函数含义
execute(operate [, param])用于执行SQL语句,返回受影响的行数。 其中,参数operation为字符串类型,表示具体的SQL语句,注意,若在SQL语句中要向外传入参数值,则该参数均使用%s表示; 参数parameters为列表类型,表示SQL语句中的参数。
fetchone()在执行查询语句时,获取查询结果集的第一行数据,返回一个元组,即(v1, v2,...)。
fetchall()在执行查询时,获取结果集的所有行,返回一个元组,即((v11, v12,...), (v21, v22,...),...)。

说明:

查询的数据结果是元组类型。

例如,使用pymysql模块来完成:

(1)使用fetchone来查询一条某xx姓名的数据信息;

(2)使用fetchall()查询出所有数据信息,并遍历出详细信息。

# 1、导入模块
import pymysql

# 2、创建连接对象
conn = pymysql.connect(
    host='192.168.88.100',
    port=3306,
    user='root',
    password='123456',
    database= 'db_students',
    charset='utf8'
)
print(conn)  # 测试一下服务器是否联通

# 3、获取游标
db_cursor = conn.cursor()


# 执行sql,进行查询
sql = 'select * from student'
db_cursor.execute(sql)

# 获取查询结果,获取一行
print(db_cursor.fetchone())

print('--------------------')
# 获取查询结果,获取多行,并遍历
result = db_cursor.fetchall()

for row2 in result:
    print(row2)

# 1、导入模块
import pymysql

# 2、创建连接对象
conn = pymysql.connect(
    host='192.168.88.100',
    port=3306,
    user='root',
    password='123456',
    database= 'db_students',
    charset='utf8'
)
print(conn)  # 测试一下服务器是否联通

# 3、获取游标
db_cursor = conn.cursor()


# 执行sql,进行查询,男性,年龄大于20岁的学生信息
gender = input('请输入你要查询的性别: ')
age = input('请输入你要查询的年龄: ')

params = [gender,age]
sql = 'select * from student where gender = %s and age > %s'  # %s 表示占位符
db_cursor.execute(sql,params)

print('--------------------')
# 获取查询结果,获取多行,并遍历
result = db_cursor.fetchall()

for row2 in result:
    print(row2)

# 5、增删改之后,一定要让操作生效,必须要提交事务,否则不生效
conn.commit()

# 6、关闭游标对象;
db_cursor.close()

# 7、关闭连接对象。
conn.close()

总结:

(1)当要获取所有查询结果数据时,可以使用fetchall()方法;

(2)注意:虽然查询数据无需提交事务,但还是建议提交一下,这样可以避免与CRUD的差异化。

五、注册与登录案例

1、注册

比如,在登录某网站前,是需要进行注册用户的。那么,注册是怎么做的呢?

其实,注册用户本质上就是给用户表添加一条数据。

例如,一起来完成:

(1)新建一个班级db_users数据库,编码为utf8;

(2)在库中新建一个用户表,字段有:编号id[主键自增]、用户名username、密码password;

(3)使用键盘录入数据的形式输入用户名、密码,并用于注册一个用户;

(4)使用DataGrip查看注册成功后的用户数据结果。

import pymysql

db_conn = pymysql.connect(
    host="localhost",
    port=3306,
    user="root",
    password="123456",
    database="db_users",
    charset="utf8"
)
db_cursor = db_conn.cursor()
# 执行插入语句
in_name = input("请输入用户名:")
in_pwd = input("请输入密码:")
params = [in_name,in_pwd]
sql = "insert into tb_user(username,password) values(%s,%s)"
db_cursor.execute(sql,params)

# 提交事务
db_conn.commit()
db_cursor.close()
db_conn.close()
print("数据注册已结束!~~")

总结:

(1)当要注册用户时,本质上实现的是插入数据功能;

(2)注意:使用pymysql模块操作注册功能时,记得进行语句参数化。

2、登录

当成功注册用户信息后,则可以进行登录操作了。那么,登录是怎么做的呢?

其实,登录账户本质上就是:查询用户数据,并与用户手动输入的用户名和密码进行匹配。

当匹配成功,则可以登录;反之,则登录失败。

例如,一起来完成:

(1)使用键盘录入数据的形式输入用户名、密码,并用于登录操作;

(2)当登录时,使用的数据内容则是已注册成功的用户表信息;

(3)观察注册成功后的用户数据,当已匹配成功,则表示成功登录。

import pymysql

db_conn = pymysql.connect(
    host="localhost",
    port=3306,
    user="root",
    password="123456",
    database="db_users",
    charset="utf8"
)
db_cursor = db_conn.cursor()
# 执行查询语句、匹配
sql = "select username,password from tb_user"
db_cursor.execute(sql)
query_result = db_cursor.fetchall()
print(query_result)

# 匹配
in_uname = input("请输入用户名:")
in_upwd = input("请输入密码:")
# for user in query_result:
for username,password in query_result:
    if in_uname == username and in_upwd == password:
        print(f"恭喜你,{username}, 已登录成功!!")
        break  # 跳出
else:
    print("登录失败!!!")

# 提交事务
db_conn.commit()
db_cursor.close()
db_conn.close()
print("数据注册已结束!~~")

总结:

(1)在Python中,如果要判断数据内容是否匹配成功可以使用if语句

(2)注意:在实际应用中,登录和注册功能可能还会涉及到用户数据加密,比如MD5加密、SHA1加密等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/798509.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Git从入门到精通】——Git常用命令总结

🎼个人主页:【Y小夜】 😎作者简介:一位双非学校的大二学生,编程爱好者, 专注于基础和实战分享,欢迎私信咨询! 🎆入门专栏:🎇【MySQL&#xff0…

购物系统 (GUI)

一、前言 1 研究背景 随着电子商务的快速发展,越来越多的消费者选择在网上购物。为了提高用户体验、提升交易效率和管理便捷性,许多企业和个人开始开发和使用各种类型的购物系统商城。而基于Java Swing的购物系统商城正是应运而生的一种应用。Java Swi…

C++中链表的底层迭代器实现

大家都知道在C的学习中迭代器是必不可少的,今天我们学习的是C中的链表的底层迭代器的实现,首先我们应该先知道链表的底层迭代器和顺序表的底层迭代器在实现上有什么区别,为什么顺序表的底层迭代器更加容易实现,而链表的底层迭代器…

更换Mac硬盘后如何将数据恢复到新驱动器?

在本文中,我们将分享几种在用新 Mac 硬盘替换旧 Mac 硬盘后从旧 Mac 硬盘恢复数据的方法。 您是否最近由于存储空间不足或损坏问题而必须更换新的Mac硬盘?是否要将受影响驱动器中的数据恢复到新驱动器?我们可以帮忙!但是&#xf…

线性代数|机器学习-P24加速梯度下降(动量法)

文章目录 1. 概述2. 引入3. 动量法梯度下降 1. 概述 我们之前学的最速梯度下降[线搜索方法] 公式如下: x k 1 x k − s k ∇ f ( x k ) \begin{equation} x_{k1}x_k-s_k\nabla f(x_k) \end{equation} xk1​xk​−sk​∇f(xk​)​​ 但对于这种方法来说&#xff…

手机数据恢复篇:如何从 Android 设备内恢复数据

如何从 Android 内部存储恢复数据? 要从 Android 内部存储恢复已删除的文件,您需要一个 Android 内部存储恢复应用或程序。请继续阅读以获取可靠的 Android 数据恢复软件,并让它帮助您从 Android 手机的内部存储恢复数据。 是否有可能恢复 An…

【vue3-命名规范以及注意事项】

使用多字组件名 使用详细的道具定义props 在提交的代码中,prop定义应该总是尽可能详细,至少指定类型。 在声明期间,道具名应该始终使用camelCase。当在in-DOM模板中使用时,props应该是串式的。单文件组件模板和JSX可以使用keba…

sklearn之神经网络学习算法

文章目录 什么是神经网络人工神经网络的结构输入层输出层隐含层神经元的链接 近几年深度学习还是比较火的,尤其是在大语言模型之后,在本质上深度学习网络就是层数比较多的神经网络。sklearn并不支持深度学习,但是支持多层感知机(浅…

AI 歌词创作:突破想象,惊艳听觉

在音乐的世界里,歌词是触动心灵的钥匙,是引发共鸣的桥梁。而如今,AI 歌词创作正以其惊人的力量,突破我们的想象,为我们带来前所未有的听觉盛宴。 “妙笔生词智能写歌词软件(veve522)”便是这场…

【机器学习-00】机器学习是什么?

在科技飞速发展的今天,机器学习已成为一个热门话题,广泛应用于各个行业和领域。那么,机器学习到底是什么?它又是如何工作的?本文将深入探讨机器学习的定义、原理及其在各领域的应用,带领读者走进这个神秘而…

QuantML-Qlib Model | ICLR 24: 基于独立Patch的时序预测模型

QuantML-Qlib Model | ICLR 24: 基于独立Patch的时序预测模型 原创 QuantML QuantML 2024年07月12日 19:23 上海 Content 论文提出了一种新的时间序列嵌入方法,主要观点是独立地嵌入时间序列块(patches),而不是捕捉这些块之间的…

MySQl高级篇-主从复制

主从复制 复制的基本原理 slave会从master读取binlog来进行数据同步 MySQL复制过程分成三步: master将改变记录到二进制日志(binary log)。这些记录过程叫做二进制日志事件,binary log events;slave将master的binary log events拷贝到它的中继日志(r…

SpringBoot+Vue实现简单的文件上传(txt篇)

SpringBootVue实现简单的文件上传 1 环境 SpringBoot 3.2.1&#xff0c;Vue 2&#xff0c;ElementUI 2 页面 3 效果&#xff1a;只能上传txt文件且大小限制为2M&#xff0c;选择文件后自动上传。 4 前端代码 <template><div class"container"><el-…

2024-07-13 Unity AI状态机2 —— 项目介绍

文章目录 1 项目介绍2 模块介绍2.1 BaseState2.2 ...State2.2.1 PatrolState2.2.2 ChaseState / AttackState / BackState 2.3 StateMachine2.4 Monster 3 其他功能4 类图 项目借鉴 B 站唐老狮 2023年直播内容。 点击前往唐老狮 B 站主页。 1 项目介绍 ​ 本项目使用 Unity 2…

SQL 字段类型-上

总 数据类型关键字描述整数迷你整型tinyint使用1个字节存储整数短整型smallint使用2个字节存储整数中整型mediumint使用3个字节存储整数标准整型int使用4个字节存储整数小数大整型bigint使用8个字节存储单进度float (.. , ..)使用4个字节 ...表示宽度 后面的... 表示小数位双精…

链接追踪系列-08.mac m1安装logstash-番外

下载地址&#xff1a;https://elasticsearch.cn/download/ 配置es相关&#xff1a; #安装plugin&#xff1a; jelexbogon bin % ./logstash-plugin install logstash-codec-json_lines启动&#xff1a;指定配置文件运行 jelexbogon bin % nohup ./logstash -f ../config…

docker安装mysql, 虚拟机连接mysql

docker已安装&#xff1a;安装教程docker和docker的安装-CSDN博客docker是容器技术&#xff08;软件&#xff09;&#xff0c;提供标准的应用镜像&#xff08;包含应用&#xff0c;和应用的依赖&#xff09;可以轻松在docker里安装应用&#xff0c;每个应用独立容器。https://b…

Linux系列--命令详解

目录 一、Linux资源管理方式 二、查询类型命令详解 三、文件管理类型命令详解 四、文件压缩与解压 五、文件编辑 六、系统命令 七、文件内容查看命令 一、Linux资源管理方式 linux操作系统采用一个文档树来组织所有的资源。这棵树的根目录的名字叫做&#xff1a;//…

Spring AOP 实现 Excel 导出统一处理

你好&#xff0c;我是柳岸花开。在实际开发中&#xff0c;经常会遇到需要导出 Excel 数据的需求。为了避免代码重复&#xff0c;我们可以使用 Spring AOP&#xff08;面向切面编程&#xff09;来实现 Excel 导出的统一处理。本文将介绍如何使用 Spring AOP 在项目中统一处理 Ex…

三参数陷波器

传统陷波器特性 传统陷波器的传递函数为&#xff1a; 传统陷波器的 Bode 图如图所示&#xff0c;根据图中曲线表明&#xff0c;当ξ 0.1、ξ 1、 ξ 10 时&#xff0c;随着ξ 值的增加&#xff0c;陷波宽度增大&#xff0c;陷波幅值也增大&#xff0c;此时&#xff0c;陷波…