zoukankan      html  css  js  c++  java
  • pymysql模块的使用

    pymysql模块的使用

    本节重点:

    •   pymysql的下载和使用
    •   execute()之sql注入
    •   增、删、改:conn.commit()
    •   查:fetchone、fetchmany、fetchall

    一、pymysql的下载

      之前我们都是通过MySQL自带的命令行客户端工具mysql来操作数据库,那如何在python程序中操作数据库呢?这就用到了pymysql模块,该模块本质就是一个套接字客户端软件,使用前需要事先安装。

    pip3 install pymysql

    二、pymysql的使用

    实现:使用Python实现用户登录,如果用户存在则登录成功(假设该用户已在数据库中)

    import pymysql
    user = input('请输入用户名:').strip()
    pwd = input('请输入密码:').strip()
    
    # 1.连接
    #创建一个连接对象<pymysql.connections.Connection object at 0x005F2910>
    conn = pymysql.connect(host='192.168.76.136', port=3306, user='root', password='root', db='db1', charset='utf8')
    
    # 2.创建游标
    #创建一个游标对象<pymysql.cursors.Cursor object at 0x005E0290>
    cursor = conn.cursor()
    
    #注意%s需要加引号
    sql = 'select * from user where  username="%s" and password="%s"'%(user, pwd)
    
    print(sql)
    
    # 3.执行sql语句
    result = cursor.execute(sql) #执行sql语句,返回sql查询成功的记录数目,不是查询内容
    print(result)
    
    # 4.关闭连接,游标和连接都要关闭
    cursor.close()
    conn.close()
    
    #打印结果时可以根据判断输出不同结果
    if result:
        print('登陆成功')
    else:
        print('登录失败')
    
    或
    print('登录成功') if res else print('登录失败')

    三、execute()之sql注入

    最后那一个空格,在一条sql语句中如果遇到select * from userinfo where username='user1' -- asadasdas' and pwd='' 则--之后的条件被注释掉了(注意--后面还有一个空格)

    #1、sql注入之:用户存在,绕过密码
    user1' -- 任意字符

     

    #2、sql注入之:用户不存在,绕过用户与密码
    xxx' or 1=1 -- 任意字符

    解决方法: 

    # 原来是我们对sql进行字符串拼接
    # sql="select * from userinfo where name='%s' and password='%s'" %(username,pwd)
    # print(sql)
    # result=cursor.execute(sql)
    
    #改写为(execute帮我们做字符串拼接,我们无需且一定不能再为%s加引号了)
    sql="select * from userinfo where name=%s and password=%s" #!!!注意%s需要去掉引号,因为pymysql会自动为我们加上
    result=cursor.execute(sql,[user,pwd]) #pymysql模块自动帮我们解决sql注入的问题,只要我们按照pymysql的规矩来。
    
    sql = 'select * from user where  username=%s and password=%s'
    res = cursor.execute(sql, (user, pwd))

    四、增、删、改:conn.commit()

    commit()方法:在数据库里增、删、改的时候,必须要进行提交,否则插入的数据不生效。

    import pymysql
    
    user = input('请输入用户名:').strip()
    pwd = input('请输入密码:').strip()
    
    conn = pymysql.connect(host='192.168.76.136', port=3306, user='root', password='root', db='db1', charset='utf8')
    cursor = conn.cursor()

    #定义insert语句

    sql_insert = 'insert into user (username, password) values (%s, %s)'
    
    res = cursor.execute(sql_insert, (user, pwd))
    #一定要commit
    conn.commit()
    
    cursor.close()
    conn.close()
    
    print('登录成功') if res else print('登录失败')
    
    mysql> select * from user;
    +----+----------+----------+----------------+
    | id | username | password | emall          |
    +----+----------+----------+----------------+
    |  1 | user1    |      123 | user1@test.com |
    |  2 | user2    |      123 | user2@test.com |
    |  3 | user3    |      123 | NULL           |
    +----+----------+----------+----------------+

    #添加多条记录,参数是一个列表中的多个集合

    res = cursor.executemany(sql_insert, [('aaa',123),('bbb',123)])
    conn.commit()
    cursor.close()
    conn.close()
    
    mysql> select * from user;
    +----+----------+----------+----------------+
    | id | username | password | emall          |
    +----+----------+----------+----------------+
    |  1 | user1    |      123 | user1@test.com |
    |  2 | user2    |      123 | user2@test.com |
    |  3 | user3    |      123 | NULL           |
    |  4 | aaa      |      123 | NULL           |
    |  5 | bbb      |      123 | NULL           |
    +----+----------+----------+----------------+

    #定义修改update语句

    sql_update = 'update user set username = %s where id=2'
    res = cursor.execute(sql_update, user)
    conn.commit()
    cursor.close()
    conn.close()
    
    mysql> select * from user;
    +----+----------+----------+----------------+
    | id | username | password | emall          |
    +----+----------+----------+----------------+
    |  1 | user1    |      123 | user1@test.com |
    |  2 | test1    |      123 | user2@test.com |
    |  3 | user3    |      123 | NULL           |
    |  4 | aaa      |      123 | NULL           |
    |  5 | bbb      |      123 | NULL           |
    +----+----------+----------+----------------+

    #定义删除delete语句

    sql_delete = 'delete from user where id=4'
    res = cursor.execute(sql_delete)
    conn.commit()
    cursor.close()
    conn.close()
    
    mysql> select * from user;
    +----+----------+----------+----------------+
    | id | username | password | emall          |
    +----+----------+----------+----------------+
    |  1 | user1    |      123 | user1@test.com |
    |  2 | test1    |      123 | user2@test.com |
    |  3 | user3    |      123 | NULL           |
    |  5 | bbb      |      123 | NULL           |
    +----+----------+----------+----------------+

    五、查:fetchone、fetchmany、fetchall

    fetchone():获取下一行数据,第一次为首行,可多次执行。
    fetchall():获取所有行数据源
    fetchmany(4):获取4行数据,n可指定

    查看表内容:

    1、fetchone()

    import pymysql
    conn = pymysql.connect(host='192.168.76.136', port=3306, user='root', password='root', db='db1', charset='utf8')
    cursor = conn.cursor()
    
    #定义查询语句
    sql_select = 'select * from user '
    
    res = cursor.execute(sql_select)
    
    row = cursor.fetchone()
    print(row)
    row = cursor.fetchone()
    print(row)
    
    cursor.close()
    conn.close()
    
    结果:每执行一次查询一行,可多次执行逐行查看
    (1, 'user1', 123, 'user1@test.com')
    (2, 'test1', 123, 'user2@test.com')

    2、fetchmany(n)

    row = cursor.fetchmany(3)
    print(row)
    结果:显示3条记录
    ((1, 'user1', 123, 'user1@test.com'), (2, 'test1', 123, 'user2@test.com'), (3, 'user3', 123, None))

    3、cursor.fetchall()

    row = cursor.fetchall()
    print(row)
    结果:显示所有记录
    ((1, 'user1', 123, 'user1@test.com'), (2, 'test1', 123, 'user2@test.com'), (3, 'user3', 123, None), (5, 'bbb', 123, None))

    4、DictCursor

    默认情况下,我们获取到的返回值是元组,在获取数据的时候并不方便,可以使用以下方式来返回字典,每一行的数据都会生成一个字典:
    #在实例化conn的时候,将属性cursor设置为pymysql.cursors.DictCursor
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    
    结果:
    [{'id': 1, 'username': 'user1', 'password': 123, 'emall': 'user1@test.com'}, {'id': 2, 'username': 'test1', 'password': 123, 'emall': 'user2@test.com'}, {'id': 3, 'username': 'user3', 'password': 123, 'emall': None}, {'id': 5, 'username': 'bbb', 'password': 123, 'emall': None}]

    5、指针位置移动

    在fetchone示例中,在获取行数据的时候,可以理解开始的时候,有一个行指针指着第一行的上方,获取一行,它就向下移动一行,所以当行指针到最后一行的时候,就不能再获取到行的内容,所以我们可以使用如下方法来移动行指针:
    
    cursor.scroll(1,mode='relative')  # 相对当前位置移动
    cursor.scroll(2,mode='absolute') # 相对绝对位置移动
    第一个值为移动的行数,整数为向下移动,负数为向上移动,mode指定了是相对当前位置移动,还是相对于首行移动
    
    sql = 'select * from user'
    cursor.execute(sql)
    
    # 查询第一行的数据
    row = cursor.fetchone()
    print(row) 
    
    # 查询第二行数据
    row = cursor.fetchone()
    print(row)
    
    cursor.scroll(-1,mode='relative') #设置之后,光标相对于当前位置(第3行)往前移动了一行,所以打印的结果为第二行的数据
    row = cursor.fetchone() 
    print(row)
    
    cursor.scroll(0,mode='absolute') #设置之后,光标相对于首行没有任何变化,所以打印的结果为第一行数据
    row = cursor.fetchone() 
    print(row)
  • 相关阅读:
    centos 7 pip install MySQL-python 报错
    修改centos history记录数上限
    CentOS 7 如何设置为eth0网卡
    字符串判空有空格报错:binary operator expected
    Linux指定用户运行程序
    MySQL 新建用户,为用户授权,指定用户访问数据库
    解决linux 中文乱码
    UNIX目录访问操作
    通过lseek产生空洞文件
    lseek系统调用
  • 原文地址:https://www.cnblogs.com/dxnui119/p/10181008.html
Copyright © 2011-2022 走看看