pymysql模块

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()

            
            
            
            
            


    
pymysql模块
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()

            
            
            
            
            


    
pymysql模块