通过PyMySQL库操作数据库
之前都是通过命令行窗口和Navicat这种交互界面进行操作,现在要开始使用Python操作MySQL来进行自动化操作了. Python需要第三方库PyMySQL来操作MySQL数据库. 通过查询数据来看基本使用方法:import pymysql # 创建连接 conn = pymysql.connect(host='localhost', user='root', password='', database='mydb') # 在建立连接之后,通过连接创建游标,之后对数据库的具体操作,都是通过游标进行 cursor = conn.cursor() sid = input('id>>>') # 写sql语句,是字符串,可以用占位符变量 sql = "select * from student where sid < {}".format(sid) # 这里需要通过游标拿到结果,结果是一个大的元组,每一条数据是其中一个元组.执行结果是受影响的行数(不是行号) effect_row = cursor.execute(sql) # 用fetchall和fetchone都可以获得结果,每执行一次fetchone,游标位置会向下走1 res = cursor.fetchone() # 关闭游标和连接 cursor.close() conn.close() print(effect_row) print(res)
上边的程序实际上就是输入一个sid,然后在student表里查询所有sid小于这个数字的结果,然后通过cursor的fetchone方法来拿到了第一个结果.有点类似于文件句柄,在查询结束以后,应该将游标和数据库连接都关闭
结果发现显示了乱码,后来发现,需要在实例化连接对象的时候,指定charset关键字参数的值为'utf8',此外还可以修改PyMySQL的配置文件connections.py,将DEFAULT_CHARSET从latin1改为utf8就可以了.如果修改了后者,则无需每次实例化的时候指定charset参数了.
实例化连接对象
MySQL数据库是通过socket连入的.PyMySQL用connect方法来生成一个数据库连接.connect的常用参数 | |
host | 字符串组成的ip地址,如果是本机,可以用'localhost'表示 |
user | 用户名 |
password | 密码 |
database | 数据库名 |
port | MySQL使用的端口,默认是3306的端口 |
charset | 指定使用的字符集,一般使用utf-8,需要数据库也是按照utf-8编码 |
CURSOR
连接成功之后,通过连接的cursor方法创建一个游标,这个游标类似于文件操作里的文件指针,是数据库的指针.后边的fetch类方法实际上与这个指针相关.
cursor的方法 | |
close() | 关闭游标 |
mogrify(query, args=None) | 返回刚刚执行的execute的sql语句,必须将自己定义的query语句作为参数,可以直接返回传输给MySQL的语句.如果没有执行过exe,则会报错 |
execute(query, args=None) | 最重要的方法,执行query语句,query是自己编写的字符串SQL语句,后边args可以传入占位符列表或者字典,用以拼接字符串.注意,execute的占位符只支持C语言风格的%s,不支持python风格的{} |
executemany(query, args) | args是一个序列,每个元素是一组参数,会将每组参数使用到query上,可以一次性执行多个参数的操作,常用在一次性insert多个数据的时候 |
fetchone() | fetch系列,拿当前游标的下一行,实际内部操作一个rownumber变量.从cursor类的初始化里可以看出,初始化cursor对象的时候rownumber被设置为0.fetchone执行之后,游标数会+1 |
fetchmany(size=None) | 一次取多行,不指定size则取下一行并将游标下移一行,指定size则一次性取出等于size的行,并将游标下移size行 |
fetchall() | 一次性取出全部行,并且将游标移动到数据结尾.注意,尽量少用此数据,会占用大量内存,最好是通过变量和limit语句来控制 |
scroll(value, mode='relative') | 移动游标,默认为相对移动,value为负数则上移,正数为下移.如果mode设置为absolute,则表示绝对定位,此时value不能为负,也不能超过最大值.游标的起始位置是0. |
此外,默认cursor对象返回的是元组,这个元组是不包含行名的,其实可以修改cursor返回的类型,让其返回字典类型,这需要在实例化cursor对象的时候指定,将上边程序修改一下:
# cursor变成字典类型 import pymysql conn = pymysql.connect( host='localhost', user='root', password='', database='mydb', charset='utf8') cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) sid = input('id>>>') sql = "select * from student where sid < %s" cursor.execute(sql,sid) res = cursor.fetchmany(3) # 游标索引开始是0,取前三行内容,游标指向了3 print(res) cursor.scroll(2) # 游标下移2,指向了5 res2 = cursor.fetchone() # 取出来的是第6行数据 print(res2) cursor.close() conn.close()取多行的时候,得到的是一个字典列表,取单行的时候,得到的就是一个字典,键是列名,数据是值.
# print(res)的结果 [{'sid': 1, 'gender': '男', 'class_id': 1, 'sname': '理解'}, {'sid': 2, 'gender': '女', 'class_id': 1, 'sname': '钢蛋'}, {'sid': 3, 'gender': '男', 'class_id': 1, 'sname': '张三'}] # print(res2)的结果 res1的结果是{'sid': 6, 'gender': '男', 'class_id': 1, 'sname': '张四'}如果对数据库执行了增加,删除,修改,在cursor所有的操作完成以后,必须执行连接对象conn.commit()方法提交修改,之后再关闭游标和连接,否则不会生效.查询则无需commit.
获得新插入数据的自增ID
经过查询从MySQL中获得数据之后,就可以对其操作了.剩下的主要是修改数据.修改的语句不再赘述,但是修改之后经常需要得到修改后最后的id用于定位.
import pymysql conn = pymysql.connect( host='localhost', user='root', password='', database='mydb', charset='utf8') cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) gender = input('gender>>>') classid = int(input('classid>>>')) name = input('name>>>') sql = "insert into student (gender,class_id,sname) values (%s,%s,%s)" cursor.execute(sql, (gender, classid, name)) conn.commit() print(cursor.lastrowid) cursor.close() conn.close()这个时候cursor.lastrowid就会返回最后一行的对应的自增id.注意,这个自增id并不是表里总共有多少行,也不是游标的索引.在不截断数据表的情况下,这个表里删除过数据,再增加,自增id依然会按照原来的继续增加. 在没有删除过任何记录的情况下,这个id才等于总行数.
用户权限管理
无论是在命令行窗口还是python,目前使用的都是无密码的root用户,这个用户是MySQL初始化生成的.root是MySQL的管理员账户,有全部的权限.在生产环境中,DBA才有数据库的管理权限,一般用户大部分只能查询,少部分可以增加,很少会发放删除和修改权限.用户权限的设置,是通过建立用户,然后给用户赋予权限实现的.
MySQL的用户数据全部保存在Mysql数据库的user表内,创建用户就会导致MySQL修改此表,由于该表的数据和相关结构非常重要,不建议直接修改此表,最好通过命令操作.
新建和修改用户名和密码 | ||
新增用户 | CREATE USER username | 建立一个叫username的用户,可以不指定密码 |
CREATE USER username IDENTIFIED BY 'string' | 可以加上IDENTIFIED BY子句创建密码,后边为纯文本密码,MysQL会将密码的hash值存储到user表内的authenticating_string列内 | |
username@host | 所有对用户的操作,用户名后边都可以加上@地址,MySQL的权限是结合用户和地址的,如果不给出地址,则默认为%,即所有地址都可以. | |
删除用户 | DROP USER username | 删除一个用户,会将这个用户所有的权限和用户名本身都删除 |
修改用户 | RENAME USER old_name TO new_name | 重命名用户 |
SET PASSWORD FOR username ='new_password' | 修改用户的密码 |
新建的用户没有任何权限,登陆MySQL之后,仅能看到information_schema这个数据库,里边存放的是MySQL的各种帮助信息.而且也不能建立数据库,为了让用户能够使用数据库,必须给用户授予权限
用户权限设置 | |
SHOW GRANTS FOR username | 显示用户的权限,如果只有USAGE ON *.* 表示没有任何权限 |
GRANT privilege ON database_name.table.name TO username | MySQL的权限是动作结合数据库以及表的,可以详细到某个数据库的某个表的权限,privilege部分可以用逗号隔开多个权限 |
REVOKE privilege ON database_name.table.name FROM username | REVOKE FROM 用来撤销权限,被撤销的权限必须存在,否则报错.privilege部分可以用逗号隔开多个权限 |