Python操作mysql数据库

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: Python操作mysql数据库

python 操作mysql

python与MySQL交互

Hello,大家好,我是景天,今天我们来一起探讨下python来对MySQL数据库进行操作。

要把python操作的数据保存到数据库需要用到pymysql

需要安装pymysql第三方包:

pip3 install pymysql

pymysql使用:

导入pymysql

import pymysql

1、创建连接对象

调用pymysql模块中的connect()函数来创建连接对象

conn = connect(参数列表)

参数host:连接mysql的主机ip,如果是本机就用’localhost’

参数port:连接mysql主机的端口号,默认是3306

参数user:连接mysql的用户名

参数password:连接密码

参数database:连接的数据库名称

参数charset:设置通信的编码格式,推荐使用utf8mb4

连接对象操作说明:

关闭连接:conn.close()

提交数据:conn.commit()

撤销数据:conn.rollback()

2、获取游标对象

获取游标对象的目的就是要执行sql语句,完成对数据库的增删改查

#调用连接对象的cursor()函数来获取游标对象

cur = conn.cursor()

游标操作说明:

使用游标执行sql语句:execute(operation, paramaters)执行sql语句,里面放sql语句。返回受影响的行数

主要执行insert update delete select等语句

paramaters可以是元祖,列表,字典

获取查询结果集中的一条数据:cur.fetchone() 返回一个元祖,如(1, ‘张三’)

获取查询结果集中的所有数据:cur.fetchall() 返回一个元祖,如((1, ‘张三’),(2, ‘李四’))

关闭游标: cur.close()表示和数据库操作完成

cursor用来执行命令的方法:

 callproc(self, procname, args):用来执行存储过程,接收的参数为存储过程名和参数列表,返回值为受影响的行数

 execute(self, query, args):执行单条sql语句,接收的参数为sql语句本身和使用的参数列表,返回值为受影响的行数

 executemany(self, query, args):执行单挑sql语句,但是重复执行参数列表里的参数,返回值为受影响的行数

 nextset(self):移动到下一个结果集

 cursor用来接收返回值的方法:

 fetchall(self):接收全部的返回结果行. 返回一个元祖,如((1, ‘张三’),(2, ‘李四’))

 fetchmany(self, size=None):接收size条返回结果行.如果size的值大于返回的结果行的数量,

则会返回cursor.arraysize条数据. 返回一个元祖,如((1, ‘张三’),(2, ‘李四’))

 fetchone(self):返回一条结果行. 返回一个元祖,如(1, ‘张三’)

 scroll(self, value, mode=‘relative’):移动指针到某一行.如果mode=‘relative’,

则表示从当前所在行移动value条,如果mode=‘absolute’,则表示从结果集的第一 行移动value条.

pymysql.connect() 参数含义

host=None, # 要连接的主机地址

user=None, # 用于登录的数据库用户

password=‘’, # 密码

database=None, # 要连接的数据库

port=0, # 端口,一般为 3306

unix_socket=None, # 选择是否要用unix_socket而不是TCP/IP

charset=‘’, # 字符编码

sql_mode=None, # Default SQL_MODE to use.

read_default_file=None, # 从默认配置文件(my.ini或my.cnf)中读取参数

conv=None, # 转换字典

use_unicode=None, # 是否使用 unicode 编码

client_flag=0, # Custom flags to send to MySQL. Find potential values in constants.CLIENT.

cursorclass=, # 选择 Cursor 类型

init_command=None, # 连接建立时运行的初始语句

connect_timeout=10, # 连接超时时间,(default: 10, min: 1, max: 31536000)

ssl=None, # A dict of arguments similar to mysql_ssl_set()'s parameters.For now the capath and cipher arguments are not supported.

read_default_group=None, # Group to read from in the configuration file.

compress=None, # 不支持

named_pipe=None, # 不支持

no_delay=None, #

autocommit=False, # 是否自动提交事务,默认不自动提交

db=None, # 同 database,为了兼容 MySQLdb

passwd=None, # 同 password,为了兼容 MySQLdb

local_infile=False, # 是否允许载入本地文件

max_allowed_packet=16777216, # 限制 LOCAL DATA INFILE 大小

defer_connect=False, # Don’t explicitly connect on contruction - wait for connect call.

auth_plugin_map={}, #

read_timeout=None, #

write_timeout=None,

bind_address=None # 当客户有多个网络接口,指定一个连接到主机

3、基本语法

“”"

(1) 创建连接对象 host user password database 这四个参数必写

conn = pymysql.connect( host=“127.0.0.1” , user=“root” , password=“123456” , database=“db003” , charset=“utf8mb4” , port=3306 )

(2) 创建游标对象 (用来操作数据库的增删改查)

cursor = conn.cursor()

print(cursor)

游标对象


(3) 执行sql语句

sql = “select * from employee”

#执行查询语句返回的总条数

res = cursor.execute(sql)

print(res)

(4) 获取数据 fetchone 获取一条

(4) 获取数据 fetchone 获取一条数据

#返回的是元组,里面包含的是第一条的完整数据

res = cursor.fetchone()

print(res)

res = cursor.fetchone()

print(res)

res = cursor.fetchone()

print(res)

(5) 释放游标对象

cursor.close()

(6) 释放连接对象

conn.close()

“”"

3、创建/删除 表操作

#conn = pymysql.connect(host=“127.0.0.1”,user=“root”,password=“123456”,database=“db003”)

#cursor = conn.cursor()

1.创建一张表

sql = """
create table t1(
id int unsigned primary key auto_increment,
first_name varchar(255) not null,
last_name varchar(255) not null,
sex tinyint not null,
age tinyint unsigned not null,
money float
);
"""
#res = cursor.execute(sql)
#print(res) # 无意义返回值

2.查询表结构

sql = “desc t1”

res = cursor.execute(sql)

print(res) # 返回的是字段的个数

res = cursor.fetchone()

print(res)

res = cursor.fetchone()

print(res)

res = cursor.fetchone()

print(res)

3.删除表

try:

sql = “drop table t1”

res = cursor.execute(sql)

print(res) # 无意义返回值

except:

pass

4、事务处理

pymysql 默认开启事务的,所有增删改的数据必须提交,否则默认回滚;rollback

所以,事务处理必须commit

conn = pymysql.connect(host="127.0.0.1",user="root",password="123456",database="db003")
cursor = conn.cursor()
sql1 = "begin"
sql2 = "update employee set emp_name='程咬钻石' where id = 18 "
sql3 = "commit"

res1 = cursor.execute(sql1)
res1 = cursor.execute(sql2)
res1 = cursor.execute(sql3)
# 一般在查询的时候,通过fetchone来获取结果
res1 = cursor.fetchone()
print(res1)


cursor.close()
conn.close()


执行更新语句,返回1,表示执行成功

5、sql 注入攻击

sql注入与防止sql注入:

什么是sql注入:

用户提交带有恶意的数据与sql语句进行字符串形式的拼接,从而影响了SQL语句的语义,最终产生了数据泄露的现象

如何防止sql注入:

sql语句参数化:

sql语言中的参数使用%s来占位,此处不是python格式化字符串操作

将sql语句中%s占位所需要的的参数存在一个列表中,把参数列表传递给ececute()方法中的第二个参数

(1) sql注入的现象

import pymysql

''' 现象:绕开账号密码登录成功 '''
'''
user = input("请输入您的用户名>>>")
pwd  = input("请输入您的密码>>>")

conn = pymysql.connect(host="127.0.0.1" , user="root" , password="123456",database="db005")
cursor = conn.cursor()
sql1 = """
create table usr_pwd(
id int unsigned primary key auto_increment,
username varchar(255) not null,
password varchar(255) not null
)
"""
sql2 = "select * from usr_pwd where username='%s' and password='%s' " % (user,pwd)
print(sql2)
res = cursor.execute(sql2)
print(res) # 1查到成功 0没查到失败
# res=cursor.fetchone()    
"""
select * from usr_pwd where username='2222' or 4=4 -- aaa' and password='' 
相当于 : select * from usr_pwd where 10=10; 绕开了账户和密码的判断 -- 代表的是注释;
"""
if res:
    print("登录成功")
else:
    print("登录失败")

cursor.close()
conn.close()
'''

sql中是字符串的,变量处要加引号

sql注入,-- 是sql 的注释

输入用户名时加上一个引号,单引号双引号要根据代码中sql来定,可以一种不行,可以切换另一种,然后加上 or 1 =1 – 后面全是注释

(2) 预处理机制

在执行sql语句之前,提前对sql语句中出现的字符进行过滤优化,避免sql注入攻击

execute( sql , (参数1,参数2,参数3 … ) ) execute2个参数默认开启预处理机制

填写 234234’ or 100=100 – sdfsdfsdfsdf 尝试攻击sql语句参数化:

sql语言中的参数使用%s来占位,此处不是python格式化字符串操作

将sql语句中%s占位所需要的的参数存在一个列表中,把参数列表传递给ececute()方法中的第二个参数

第二个参数可以是字符串,元祖,列表或字典

原码

user = input(“请输入您的用户名>>>”)

pwd = input(“请输入您的密码>>>”)

conn = pymysql.connect(host=“127.0.0.1” , user=“root” , password=“123456”,database=“db005”)

cursor = conn.cursor()

sql = “select * from usr_pwd where username=%s and password=%s”

res = cursor.execute(sql , (user,pwd) )

print(res)

print( “登录成功” if res else “登录失败” )

cursor.close()

conn.close()

%s占位符依次取execute()方法中的第二个参数,参数输入对才能查询成功 %s不能要任何引号

6、python 操作mysql 数据库 (增删改查)

import pymysql

python 操作mysql增删改时,默认是开启事务的,
必须最后commit提交数据,才能产生变化

提交数据: commit 
默认回滚: rollback

pymysql.connect()函数默认是不提交的,所以每次增删改之后,要想执行结果持久化到数据库需要提交事务

conn = pymysql.connect(host=“127.0.0.1”,user=“root”,password=“123456”,database=“db005”)

#默认获取查询结果时是元组,可以设置 返回字典; cursor=pymysql.cursors.DictCursor

cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)


#执行对mysql 的操作

1.增

(1) 一次插入一条
sql = "insert into t1(first_name,last_name,sex,age,money) values(%s,%s,%s,%s,%s)"

res = cursor.execute( sql , ("孙","健",0,15,20000)  )
print(res) # 1
# 获取最后插入这条数据的id号
print(cursor.lastrowid)

(2) 一次插入多条
res = cursor.executemany(  sql , [  ("安","晓东",0,18,30000) , ("刘","玉波",1,20,50000) ,("张","光旭",0,80,60000) , ("李","是元",0,10,10) , ("高","大奥",1,20,80000)   ]   )
print(res) # 返回插入的条数
# 获取插入5条数据中的第一条数据的id
print(cursor.lastrowid)
# 获取最后一个数据的id
sql = "select id from t1 order by id desc limit 1"
res = cursor.execute(sql)
print(res)
# 获取结果,返回元组
res = cursor.fetchone()
print(res["id"])
# 默认元组 : (57, '高', '大奥', 1, 20, 80000.0)
# 返回字典 : {'id': 51, 'first_name': '高', 'last_name': '大奥', 'sex': 1, 'age': 20, 'money': 80000.0}

创建游标对象时,cur = conn.cursor() 默认通过fetchone,fetchall,fetchmany获取查询结果时是元组

可以设置返回字典; 将参数 cursor=pymysql.cursors.DictCursor 放入cur = conn.cursor() 中

插入一条数据和插入多条数据,插入多条数据时,每条数据放入元祖中,多条数据多个小元祖放入到列表中

executemany() 参数可跟 字符串,列表,元祖

2.删

sql = “delete from t1 where id in (%s,%s,%s)”

res = cursor.execute(sql , (3,4,5) )

print(res) # 返回的是3,代表删除了3条

if res:

print(“删除成功”)

else:

print(“删除失败”)

防止sql注入,使用%s占位

mysql删除不存在的数据不报错

3.改

sql = “update t1 set first_name = ‘王’ where id = %s”

sql = “update t1 set first_name = ‘王’ where id in (%s,%s,%s,%s)”

res = cursor.execute(sql , (6,7,8,9))

print(res) # 返回的是4,代表修改了4条

if res:

print(“修改成功”)

else:

print(“修改失败”)

4.查

fetchone 获取一条

fetchmany 获取多条

fetchall 获取所有

sql = “select * from t1”

res = cursor.execute(sql)

print(res) # 针对于查询语句来说,返回的res是总条数;

(1) fetchone 获取一条

res = cursor.fetchone()

print(res)

res = cursor.fetchone()

print(res)

fetchone()获取的是查询的第一条

(2) fetchmany 获取多条
res = cursor.fetchmany() # 默认获取的是一条数据,返回列表,里面里面是一组一组的字典;
data = cursor.fetchmany(3)
print(data)
"""
[
    {'id': 9, 'first_name': '王', 'last_name': '是元', 'sex': 0, 'age': 10, 'money': 10.0}, 
    {'id': 10, 'first_name': '孙', 'last_name': '健', 'sex': 0, 'age': 15, 'money': 20000.0}, 
    {'id': 11, 'first_name': '安', 'last_name': '晓东', 'sex': 0, 'age': 18, 'money': 30000.0}
]
"""
for row in data:
    first_name = row["first_name"]
    last_name = row["last_name"]
    sex = row["sex"]
    if sex == 0:
        sex = "男性"
    else:
        sex = "女性"
    age = row["age"]
    money = row["money"]
    strvar = "姓:{},名:{},性别:{},年龄:{},收入:{}".format(first_name,last_name,sex,age,money)
print(strvar)

fetchmany() 参数是要获取的数量,返回的是列表,里面是一条条记录,元祖或者字典

将数据组织好发给前端

(3) fetchall 获取所有

data = cursor.fetchall()

print(data)

如果是字典方式获取,得到的是列表包含字典

(4) 自定义搜索查询的位置,从哪里开始搜索

print(“<==================>”)

默认是相对滚动

如fetchall(),fetchmany(),fetchone()同时作用于同一个查询时,每个方法执行开头是上一个方法执行的结尾

----可以通过scroll()来重置游标位置,从我们需要的位置获取我们想要的数据

1.相对滚动 relative

“”“相对于上一次查询的位置往前移动(负数),或者往后移动(正数)”“”

“”"

cursor.scroll(-1,mode=“relative”)

#cursor.scroll(5,mode=“relative”)

res = cursor.fetchone()

print(res)

“”"

上面fetchall已经查询完毕,通过滚动搜索位置,向前移一位,又可以查询到数据

2.绝对滚动 absolute

“”“永远从数据的开头起始位置进行移动,不能向前滚”“”

cursor.scroll(0,mode=“absolute”)

res = cursor.fetchone()

print(res)

conn.commit()

cursor.close()

conn.close()


从开头开始偏移,cur.scroll(0,mode=“absolute”) 表示从开头开始查询。cur.scroll(2,mode=“absolute”)表示从开头向右滚动2个后,开始查询

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
关系型数据库 MySQL 数据库连接
python脚本:连接数据库,检查直播流是否可用
【10月更文挑战第13天】本脚本使用 `mysql-connector-python` 连接MySQL数据库,检查 `live_streams` 表中每个直播流URL的可用性。通过 `requests` 库发送HTTP请求,输出每个URL的检查结果。需安装 `mysql-connector-python` 和 `requests` 库,并配置数据库连接参数。
126 68
|
2月前
|
关系型数据库 MySQL 数据处理
探索Python中的异步编程:从asyncio到异步数据库操作
在这个快节奏的技术世界里,效率和性能是关键。本文将带你深入Python的异步编程世界,从基础的asyncio库开始,逐步探索到异步数据库操作的高级应用。我们将一起揭开异步编程的神秘面纱,探索它如何帮助我们提升应用程序的性能和响应速度。
|
2月前
|
存储 缓存 Shell
你知道 Python 其实自带了小型数据库吗
你知道 Python 其实自带了小型数据库吗
20 2
你知道 Python 其实自带了小型数据库吗
|
2月前
|
Web App开发 SQL 数据库
使用 Python 解析火狐浏览器的 SQLite3 数据库
本文介绍如何使用 Python 解析火狐浏览器的 SQLite3 数据库,包括书签、历史记录和下载记录等。通过安装 Python 和 SQLite3,定位火狐数据库文件路径,编写 Python 脚本连接数据库并执行 SQL 查询,最终输出最近访问的网站历史记录。
|
2月前
|
SQL 机器学习/深度学习 数据采集
SQL与Python集成:数据库操作无缝衔接22.bijius.com
自动化数据预处理:使用Python库(如Pandas)自动清洗、转换和准备数据,为机器学习模型提供高质量输入。 实时数据处理:集成Apache Kafka或Amazon Kinesis等流处理系统,实现实时数据更新和分析。
|
2月前
|
关系型数据库 MySQL 数据库
Mysql学习笔记(四):Python与Mysql交互--实现增删改查
如何使用Python与MySQL数据库进行交互,实现增删改查等基本操作的教程。
67 1
|
2月前
|
存储 关系型数据库 数据库
轻量级数据库的利器:Python 及其内置 SQLite 简介
轻量级数据库的利器:Python 及其内置 SQLite 简介
|
2月前
|
SQL 机器学习/深度学习 数据库
SQL与Python集成:数据库操作无缝衔接
在开始之前,确保你已经安装了必要的Python库,如`sqlite3`(用于SQLite数据库)或`psycopg2`(用于PostgreSQL数据库)。这些库提供了Python与SQL数据库之间的接口。
|
2月前
|
SQL 关系型数据库 数据库
使用 PostgreSQL 和 Python 实现数据库操作
【10月更文挑战第2天】使用 PostgreSQL 和 Python 实现数据库操作
|
3月前
|
数据采集 关系型数据库 MySQL
如何用Python+sqlalchemy创建数据库
如何用Python+sqlalchemy创建数据库
下一篇
无影云桌面