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

    1.安装pymysql模块   pip install pymysql 

    2.pymysql的简单使用

    import pymysql

    user=input('用户名: ').strip()
    pwd=input('密码: ').strip()

    #链接,指定ip地址和端口,本机上测试时ip地址可以写localhost或者自己的ip地址或者127.0.0.1,然后你操作数据库的时候的用户名,密码,要指定你操作的是哪个数据库,指定库名,还要指定字符集。不然会出现乱码
    conn=pymysql.connect(host='127.0.0.1', #指定主机ip
                port=3306, #端口
                user='root', #用户
                password='123', #密码
                database='student', #指定库名
                charset='utf8') #指定编码为utf8的时候,注意没有-,别写utf-8,数据库为 #得到conn这个连接对象 #游标1 获取的结果是元组 cursor=conn.cursor() #这就想到于mysql自带的那个客户端的游标mysql> 在这后面输入指令,回车执行
    #游标2 获取的结果是字典类型
    #cursor=conn.cursor(cursor=pymysql.cursors.DictCursor) #获取字典数据类型表示的结果:{'sid': 1, 'gender': '男', 'class_id': 1, 'sname': '理解'} {'字段名':值} #然后给游标输入sql语句并执行sql语句execute sql='select * from userinfo where name="%s" and password="%s"' %(user,pwd) #注意%s需要加引号,执行这句sql的前提是医药有个userinfo表,里面有name和password两个字段,还有一些数据,自己添加数据昂 print(sql)
    #执行SQL语句 res
    =cursor.execute(sql) #执行sql语句,返回sql查询成功的记录数目,是个数字,是受sql语句影响到的记录行数,其实除了受影响的记录的条数之外,这些记录的数据也都返回了给游标,这个就相当于我们subprocess模块里面的管道PIPE,乘放着返回的数据
    print(res) #返回的是一个数字,表示受影响的行数

    #获取数据的三种方法fetchall fetchone fetchmany
    #all_data=cursor.fetchall()  #获取返回的所有数据,注意凡是取数据,取过的数据就没有了,结果都是元祖格式的
    #many_data=cursor.fetchmany(3) #一下取出3条数据,
    #one_data=cursor.fetchone()  #按照数据的顺序,一次只拿一个数据,下次再去就从第二个取了,因为第一个被取出去了,取一次就没有了,结果也都是元祖格式的
      fetchone:(1, '', 1, '理解')
      fetchone:(2, '', 1, '钢蛋')
      fetchall:((3, '', 1, '张三'), (4, '', 1, '张一'))
    #上面fetch的结果都是元祖格式的,没法看出哪个数据是对应的哪个字段,这样是不是不太好看,想一想,我们可以通过python的哪一种数据类型,能把字段和对应的数据表示出来最清晰,当然是字典{'字段名':值}
    #我们可以再创建游标的时候,在cursor里面加上一个参数:cursor=conn.cursor(cursor=pymysql.cursors.DictCursor)获取的结果就是字典格式的,fetchall或者fetchmany取出的结果是列表套字典的数据形式
    
    
    上面我们说,我们的数据取一次是不是就没有了啊,实际上不是的,这个取数据的操作就像读取文件内容一样,每次read之后,光标就移动到了对应的位置,我们可以通过seek来移动光标
    同样,我们可以移动游标的位置,继续取我们前面的数据,通过cursor.scroll(数字,模式),第一个参数就是一个int类型的数字,表示往后移动的记录条数,第二个参数为移动的模式,有两个值:absolute:绝对移动,relative:相对移动
    #绝对移动:它是相对于所有数据的起始位置开始往后面移动的 #相对移动:他是相对于游标的当前位置开始往后移动的 #绝对移动的演示 #print(cursor.fetchall()) #cursor.scroll(3,'absolute') #从初始位置往后移动三条,那么下次取出的数据为第四条数据 #print(cursor.fetchone()) #相对移动的演示 #print(cursor.fetchone()) #cursor.scroll(1,'relative') #通过上面取了一次数据,游标的位置在第二条的开头,我现在相对移动了1个记录,那么下次再取,取出的是第三条,我相对于上一条,往下移动了一条 #print(cursor.fetchone()) cursor.close() #关闭游标 conn.close() #关闭连接 if res: print('登录成功') else: print('登录失败')

    3.execute()之sql注入 

    总结两种sql注入的语句
    #1、sql注入之:用户存在,绕过密码
    chao' -- 任意字符
    
    #2、sql注入之:用户不存在,绕过用户与密码
    xxx' or 1=1 -- 任意字符

    4.execute()之sql注入 的解决方法

    # 原来是我们对sql进行字符串拼接
    # sql="select * from userinfo where name='%s' and password='%s'" %(user,pwd)
    # print(sql)
    # res=cursor.execute(sql)
    
    #改写为(execute帮我们做字符串拼接,我们无需且一定不能再为%s加引号了)
    sql="select * from userinfo where name=%s and password=%s" #!!!注意%s需要去掉引号,因为pymysql会自动为我们加上
    res=cursor.execute(sql,[user,pwd]) #pymysql模块自动帮我们解决sql注入的问题,只要我们按照pymysql的规矩来。
    示例如下:
    之前我们的sql语句是这样写的: sql
    = "select * from userinfo where username='%s' and password='%s';"%(uname,pword) 以后再写的时候,sql语句里面的%s左右的引号去掉,并且语句后面的%(uname,pword)这些内容也不要自己写了,按照下面的方式写 sql = "select * from userinfo where username=%s and password=%s;" 难道我们不传值了吗,不是的,我们通过下面的形式,在excute里面写参数: #cursor.execute(sql,[uname,pword]) ,其实它本质也是帮你进行了字符串的替换,只不过它会将uname和pword里面的特殊字符给过滤掉。 看下面的例子: uname = input('请输入用户名:') #输入的内容是:chao' -- xxx或者xxx' or 1=1 -- xxxxx pword = input('请输入密码:') sql = "select * from userinfo where username=%s and password=%s;" print(sql) res = cursor.execute(sql,[uname,pword]) #res我们说是得到的行数,如果这个行数不为零,说明用户输入的用户名和密码存在,如果为0说名存在,你想想对不 print(res) #如果输入的用户名和密码错误,这个结果为0,如果正确,这个结果为1 if res: print('登陆成功') else: print('用户名和密码错误!') #看结果: 请输入用户名:xxx' or 1=1 -- xxxxx 请输入密码: select * from userinfo where username=%s and password=%s; 用户名和密码错误!

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

    import pymysql
    #链接
    conn=pymysql.connect(host='localhost',port='3306',user='root',password='123',database='crm',charset='utf8')
    #游标
    cursor=conn.cursor()
    
    #执行sql语句
    #part1
    # sql='insert into userinfo(name,password) values("root","123456");'
    # res=cursor.execute(sql) #执行sql语句,返回sql影响成功的行数
    # print(res)
    # print(cursor.lastrowid) #返回的是你插入的这条记录是到了第几条了
    
    #part2
    # sql='insert into userinfo(name,password) values(%s,%s);'
    # res=cursor.execute(sql,("root","123456")) #执行sql语句,返回sql影响成功的行数
    # print(res)
    #还可以进行更改操作:
    #res=cursor.excute("update userinfo set username='taibaisb' where id=2")
    #print(res) #结果为1
    #part3
    sql='insert into userinfo(name,password) values(%s,%s);'
    res=cursor.executemany(sql,[("root","123456"),("lhf","12356"),("eee","156")]) #执行sql语句,返回sql影响成功的行数,一次插多条记录
    print(res)
    #上面的几步,虽然都有返回结果,也就是那个受影响的函数res,但是你去数据库里面一看,并没有保存到数据库里面,
    conn.commit() #必须执行conn.commit,注意是conn,不是cursor,执行这句提交后才发现表中插入记录成功,没有这句,上面的这几步操作其实都没有成功保存。
    cursor.close()
    conn.close()

    6.查:fetchone,fetchmany,fetchall

  • 相关阅读:
    初识NuGet
    NHibernate之映射文件配置说
    NHibernate 数据查询之QueryOver<T>
    一、NHibernate配置所支持的属性
    javascript forEach无法break,使用every代替
    missing ) after argument list
    数组分组chunk的一种写法
    call和apply第一个参数为null/undefined,函数this指向全局对象
    apply的理解和数组降维
    javascript push 和 concat 的区别
  • 原文地址:https://www.cnblogs.com/l1222514/p/11396330.html
Copyright © 2011-2022 走看看