pymysql模块
一、pymysql模块 1、说明: 想在python代码中连接上mysql数据库,就需要使用pymysql模块, pymysql是在 Python3.x 版本中用于连接 MySQL 服务器的一个库,在Python2中则使用mysqldb。 Django中也可以使用PyMySQL连接MySQL数据库。 2、 安装 在cmd窗口执行命令行:pip install pymysql # 注意:如果电脑上安装了两个版本的python解释器,则应该明确pip的版本,pip2还是pip3。 补充 pip -V --> 查看当前pip的版本 pip list --> 查看当前python解释器环境中安装的第三方包和版本(安装完成后可用此命令查看是否安装成功) 3、注意事项 应该确定你有一个MySQL数据库,并且已经启动 应该确定你有可以连接该数据库的用户名和密码 应该确定你有一个有权限操作的database 4、使用步骤 1. 导入pymysql模块 import pymysql 2. 连接database conn = pymysql.connect( host='127.0.0.1', # 数据库的IP地址 port=3306, # 数据库的端口 user='root', # 用户名 password='123abc' # 密码 database='test', # 具体的一个数据库(文件夹) charset='urf8' # 编码方式,注意:charset='utf8',不要写成'utf-8' ) 3. 获取光标对象 cursor = conn.cursor() 4. 执行SQL语句 cursor.execute('select * from userinfo;') 5. 关闭 1. 关闭光标 cursor.close() 2. 关闭连接 conn.close() 6.例子 import pymysql # 获取用户输入 name = input('请输入用户名:') pwd = input('请输入密码:') # 连接数据库,得到一个连接 conn = pymysql.connect( host='127.0.0.1', port=3306, # mysql默认端口3306 user='root', password='123abc', database='test', charset='utf8' ) # 获取光标 cursor = conn.cursor() # sql语句 sql = "select * from userinfo where username='%s' and password='%s';" % (name, pwd) print(sql) # 执行sql语句 ret = cursor.execute(sql) print(ret) # ret是受影响的记录数量,若不为空,则代表查到相应的记录 # 关闭 cursor.close() conn.close() # 结果 if ret: print('登陆成功') else: print('登录失败') 结果: 请输入用户名:ming 请输入密码:112233 select * from userinfo where username='ming' and password='112233' 1 登陆成功 5、 SQL注入问题 1. 什么是SQL注入? 用户输入的内容有恶意的SQL语句,后端拿到用户输入的内容不做检测直接做字符串拼接,得到一个和预期不一致的SQL语句 例如:上面例子的代码完全不变,但是我这样输入: 请输入用户名:ming' -- 请输入密码:12345 select * from userinfo where username='ming' -- ' and password='12345'; 1 登陆成功 结果是登录成功了,为什么? 这是因为我在输入用户名的时候,输入的是ming' -- 在sql语句中,--代表注释的意思,也就是说 select * from userinfo where username='ming' -- ' and password='12345'; 这句sql语句相当于 select * from userinfo where username='ming' 那肯定能登录成功啊,因为我数据库中就是有这个用户,相当于找用户名,有这个用户就成功,并没有去匹配密码, 这就是恶意注入的问题。 2. 如何解决SQL注入? 对用户输入的内容做检测,有引号怎么处理,注释怎么处理,过程很麻烦,但是, pymysql内置了这种检测,我们可以直接使用,所以我们不应该自己拼接sql语句,而是让pymysql帮我们拼接sql语句。 cursor.execute(sql, [name, pwd]) # 让pymysql模块帮我们拼接sql语句,执行SQL语句 例子: import pymysql # 获取用户输入 name = input('请输入用户名:') pwd = input('请输入密码:') # 连接数据库,得到一个连接 conn = pymysql.connect( host='127.0.0.1', port=3306, # mysql默认端口3306 user='root', password='123abc', database='test', charset='utf8' ) # 获取光标 cursor = conn.cursor() # sql语句:按照pymysql模块的写法定义好占位符,pymysql只有%s一种占位符 sql = "select * from userinfo where username=%s and password=%s;" print(sql) # 执行sql语句 ret = cursor.execute(sql,[name,pwd]) # 让pymysql模块帮我们拼接sql语句,执行SQL语句 print(ret) # ret是受影响的记录数量,若不为空,则代表查到相应的记录 # 关闭 cursor.close() conn.close() # 结果 if ret: print('登陆成功') else: print('登录失败') 结果1: 请输入用户名:ming' -- 请输入密码:12345 select * from userinfo where username=%s and password=%s; 0 登录失败 结果2: 请输入用户名:ming 请输入密码:112233 select * from userinfo where username=%s and password=%s; 1 登陆成功 6、pymysql的使用 涉及到修改数据库内容的时候,一定要提交:conn.commit() 1. 增、删、改 import pymysql # 连接数据库,得到一个连接 conn = pymysql.connect( host='127.0.0.1', port=3306, user='root', password='123abc', database='test', charset='utf8' ) # 获取光标 cursor = conn.cursor() # 得到SQL语句 sql1 = "insert into userinfo(username, password) values (%s,%s);" # 增 sql2 = "delete from userinfo where username=%s;" # 删 sql3 = "update userinfo set password=%s where username=%s;" # 改 # 使用光标对象执行SQL语句 cursor.execute(sql1, ['sb', '456']) # 让pymysql模块帮我们拼接sql语句,执行SQL语句 # 涉及到修改数据库内容,一定要提交 conn.commit() cursor.execute(sql2, ['ming']) conn.commit() cursor.execute(sql3, ['123', 'sb']) conn.commit() # 关闭 cursor.close() conn.close() 2. 查 1. 返回的数据类型 1. 默认返回的元组,且每个元素也是用元组 2. 可以设置为返回的是列表,列表中的每个元素是字典 cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) 2. 常用的方法 1. fetchall() 返回所有查询到的记录 2. fetchone() 返回一条查询到的记录 3. fetchmany(size) 返回size条查询到的记录 4.cursor.scroll(1, mode="absolute") 光标按绝对位置移动 5.cursor.scroll(1, mode="relative") 光标按照相对位置(当前位置)移动 例子1: import pymysql # 连接数据库,得到一个连接 conn = pymysql.connect( host='127.0.0.1', port=3306, user='root', password='123abc', database='test', charset='utf8' ) # 获取光标 cursor = conn.cursor() # 得到SQL语句 sql = "select * from userinfo;" # 使用光标对象执行SQL语句 cursor.execute(sql) # 没有参数则不用拼接,直接执行 ret = cursor.fetchall() print(ret) # 关闭 cursor.close() conn.close() 结果1: (('hong', 123), ('sb', 123), ('ming', 456), ('dong', 789)) 例子2: import pymysql # 连接数据库,得到一个连接 conn = pymysql.connect( host='127.0.0.1', port=3306, user='root', password='123abc', database='test', charset='utf8' ) # 获取光标,设置查询结果为列表且元素为字典 cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 得到SQL语句 sql = "select * from userinfo;" # 使用光标对象执行SQL语句 cursor.execute(sql) # 没有参数则不用拼接,直接执行 # 查询所有 # ret = cursor.fetchall() # print(ret) # 查询单条记录 # ret = cursor.fetchone() # print(ret) # ret = cursor.fetchone() # print(ret) # 查询指定数量的数据 ret = cursor.fetchmany(2) print(ret) # [{'username': 'hong', 'password': 123}, {'username': 'sb', 'password': 123}] print(cursor.fetchone()) # {'username': 'ming', 'password': 456} print(cursor.fetchone()) # {'username': 'dong', 'password': 789} # 移动光标 cursor.scroll(-1, mode='relative') # 相对位置,基于光标当前位置移动 print(cursor.fetchone()) # {'username': 'dong', 'password': 789} cursor.scroll(0, mode='absolute') # 绝对位置,你让光标移动到哪里就到哪里 print(cursor.fetchone()) # {'username': 'hong', 'password': 123} # 关闭 cursor.close() conn.close() 3.批量增(插入) import pymysql # 连接数据库,得到一个连接 conn = pymysql.connect( host='127.0.0.1', port=3306, user='root', password='123abc', database='test', charset='utf8' ) # 获取光标 cursor = conn.cursor() # 得到SQL语句 sql = "insert into userinfo(username, password) values (%s,%s);" # 增 # 数据 data = [("a", 18), ("b", 19), ("c", 20)] # 使用光标对象执行SQL语句 cursor.executemany(sql, data) # 批量增使用executemany # 涉及到修改数据库内容,一定要提交 conn.commit() # 关闭 cursor.close() conn.close() 5、 conn.rollback():在执行增删改操作时,如果不想提交前面的操作,可以使用 rollback() 回滚取消操作。 cursor.lastrowid:获取插入数据的ID(关联操作时会用到) # 导入pymysql模块 import pymysql # 连接数据库,得到一个连接 conn = pymysql.connect( host='127.0.0.1', port=3306, user='root', password='123abc', database='test', charset='utf8' ) # 得到一个可以执行SQL语句的光标对象 cursor = conn.cursor() # sql语句 sql = "insert into userinfo(username, password) values (%s,%s);" try: # 执行SQL语句 cursor.execute(sql, ['xiazi', 58]) # 提交 conn.commit() # 提交之后,获取刚插入的数据的ID last_id = cursor.lastrowid except Exception as e: # 有异常,回滚取消操作 conn.rollback() cursor.close() conn.close()