zoukankan      html  css  js  c++  java
  • pymysql模块

    pymysql模块

    pymysql模块是python一个操作mysql的模块。非内置模块,需要安装:

    pip3 install pymysql
    

    基本使用

    import pymysql
    
    # 连接数据库
    conn = pymysql.connect(
        host='127.0.0.1',  # 指定ip
        port=3306,  # 指定端口,注意端口号为int类型
        user='root',  # 用户名
        password='1233',  # 用户密码
        charset='utf8mb4',  # 编码不要加-
        database='day38',  # 指定操作的库
    )
    
    # cursor = conn.cursor() # 生成游标对象,用来执行SQL语句
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 该参数将查询结果变为字典类型,key为字段名,value为值。
    sql = 'select * from teacher;'
    res = cursor.execute(sql)
    print(res)  # 得到的返回值为受影响的行数。
    
    # 拿到一条查询结果,元组类型,加参数后为字典。
    # print(cursor.fetchone())
    
    # 拿到指定条数的记录,一行记录为一个元组,多条记录合并为一个大元组。
    # 加参数后为一个列表内嵌套着多个字典
    # print(cursor.fetchmany(2))
    
    # 拿到剩余所有的记录,大元组嵌套小元组,加参数后为列表嵌套多个字典。
    print(cursor.fetchall())
    # print(cursor.fetchall())  # 每读一条记录,指针都会向后移一位,所有记录都拿完后就无法再取值,所以结果为空元组或空列表。
    
    # 移动指针
    cursor.scroll(1,'relative')  # 相对指针当前位置向后移动1位。
    cursor.scroll(1,'abslute')  # 从起始位置向后移动1位。
    
    cursor.close()  # 关闭游标
    conn.close()  # 关闭连接
    

    SQL注入

    利用一些语法的特性,书写一些特定的语句实现固定的语法。

    MySQL利用的是MySQL的注释语法。

    例如写一个登录功能:

    import pymysql
    
    conn = pymysql.connect(
    	host='127.0.0.1',
        port=3306,
        user='root',
        password='1233',
        database='db1',
        charset='utf8',
    )
    
    cursor = conn.cursor()
    
    name = input('name: ').strip()
    password = input('password: ').strip()
    
    # name字段和password字段为字符,要带引号,分号带不带无所谓
    sql = f'select * from user_info where name = "{name}" and password = "{password}";'
    res = cursor.execute(sql)
    if res:
        print('登录成功!')
    else:
        print('登录失败!')
        
    cursor.close()
    conn.close()
    

    当正常输入用户名和密码时能够进行正常的判断,但如果输入的是下列特殊语句,就会造成误判甚至危害:

    1、只知道用户名,密码为空或错误也能登陆成功

    name: chirou' -- 必须有一个任意字符,注意--后面要带一个空格,引号要匹配
    password: 
    登陆成功!
    

    通过这种方式,SQL语句实际变成了:

    select * from user_info where name = "chirou" -- a" and password = "";
    

    仅判断了用户名,后面都被注释掉,不再进行判断。

    2、用户名和密码都不知道也能登陆成功

    name: xxx" or 1=1 -- asd
    password: 
    
    登录成功!
    

    SQL语句变成了:

    select * from user_info where name = "xxx" or 1=1 -- asd" and password = "";
    

    只要or后面的条件为真就能总体为真。

    解决方式

    1、限制用户输入的字符格式,尽量不要有特殊符号。

    2、不要自己用Python格式化字符串拼接。

    execute方法可以过滤掉特殊符号,帮我们完成拼接操作:

    sql = 'select * from user_info where name=%s and password=%s'  # execute只能识别%s
    
    res = cursor.execute(sql,(name,password))  # 元组或列表都行,注意顺序。
    

    这样就能避免SQL注入问题。

    pymysql的增删改查

    import pymysql
    
    conn = pymysql.connect(
        host='127.0.0.1',
        port=3306,
        user='root',
        password='1233',
        database='db1',
        charset='utf8',
        autocommit=True,  # 自动提交
    )
    
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    
    # 增
    # sql = 'insert into user_info(name,password) values(%s,%s)'
    # rows = cursor.execute(sql, ('duorou', 123))
    # print(rows)
    
    # 添加多条数据
    sql = 'insert into user_info(name,password) values(%s,%s)'
    rows = cursor.executemany(sql,[('aaa',123),('bbb',123),('ccc',123)])
    print(rows)
    
    # 改
    # sql = 'update user_info set name="hahaha" where id = 7'
    # rows = cursor.execute(sql)
    # print(rows)
    
    # 删
    # sql = 'delete from user_info where name="hahaha"'
    # rows = cursor.execute(sql)
    # print(rows)
    
    # 查
    # sql = 'select * from user_info'
    # rows = cursor.execute(sql)
    # print(rows)
    
    # 对于增删改操作,涉及到数据的变动,所以不会直接在数据看生效,需要进行二次确认,提交操作
    # conn.commit()  # 也可以在建立连接对象时指定autocommit为True,自动提交
    
    cursor.close()
    conn.close()
    

    获取插入的最后一条记录的自增ID

    import pymysql
    conn=pymysql.connect(host='localhost',port=3306,user='root',password='1233',database='db1',charset='utf8')
    cursor=conn.cursor()
    
    sql='insert into user_info(name,password) values("xxx","123");'
    rows=cursor.execute(sql)
    print(cursor.lastrowid) #在插入语句后查看
    
    conn.commit()
    
    cursor.close()
    conn.close()
    

    调用存储过程

    cursor.callproc('p1',(1,5,10))  # 第一个参数是存储过程的名称,第二个参数是存储过程的参数。
    print(cursor.fetchall())  # 查看存储过程所显示的结果。
    
    pymysql模块会将传给存储过程的参数先定义为mysql的变量,通过变量将实际的值传进去,变量命名为:
    @_p1_0 = 1
    @_p1_1 = 5
    @_p1_2 = 10
    
  • 相关阅读:
    归并排序
    将文件存储到数据库中(MySQL)
    JS实现日历控件选择后自动填充
    HDU 1358 Period KMP
    Adobe Flash Player已经终止一项可能不安全的操作,解决方案
    将文件从数据库(MySQL)中进行读取
    Ubuntu java开发环境配置
    硬盘结构和原理
    杭电 HDU 1242 Rescue
    mysql workbench建表时PK,NN,UQ,BIN,UN,ZF,AI
  • 原文地址:https://www.cnblogs.com/ChiRou/p/14513812.html
Copyright © 2011-2022 走看看