python学习笔记 day45 pymysql
1. 使用pymysql模块实现python与数据库的交互
需求: python实现用户登录,用户输入用户名和密码,然后用户信息都保存在userinfo数据库中,可以借助pymysql模块实现python和数据库的交互,来模拟用户登录~
首先我们先创建一个userinfo表:
在python中借助pymysql模块(不推荐!!)
import pymysql usm=input("username:") pwd=input("password:") conn=pymysql.connect(host="localhost",user="root",password="******(你登录mysql的密码)",database="db666") # connect()中的参数 host是哪一台主机上安装了mysql 接着是mysql登录的用户名和密码 以及所要操作连接的数据库 cursor=conn.cursor() # 可以拿着cursor去操作执行数据库中的语句 sql="select * from userinfo where username='%s' and password='%s'"%(usm,pwd) cursor.execute(sql) # 使用cursor.execute(sql)去执行sql语句----select * from userinfo where username= and password= result=cursor.fetchone() # 获得查询一条查询结果,如果查到相应的数据,就会返回查到的结果给result(fetchone()只可以查到一条记录) cursor.close() # 关闭数据库 conn.close() print(result) # 会打印查询的结果
运行结果:
上面在写sql语句时采用了字符串拼接的形式,一定要注意!!千万不能这样写,因为:
就是因为上面sql语句使用了字符串拼接的操作,专业术语叫做sql注入;
其实你会发现当输入的用户名为xuanxuna‘ -- 时 sql语句就相当于执行了 ’select * from userinfo where username="xuanxuan' --' and password='%s' " 显然 password那部分使用--直接就注释掉了!!
所以sql注入会有安全隐患!!
正确做法应该是,当所要执行的sql语句需要传入参数时,我们应该在cursor.execute()中传入相应的参数 来防止sql注入,pymysql会自动帮我们去执行相应的填充操作!!
import pymysql usm=input("username:") pwd=input("password:") conn=pymysql.connect(host="localhost",user="root",password="*******",database="db666") # 数据库的连接 cursor=conn.cursor() sql="select * from userinfo where username=%s and password=%s" # 需要执行的sql语句,但是不能使用字符串的拼接(sql注入很不安全(注意%s不加引号!!!) cursor.execute(sql,[usm,pwd]) # 将所要执行的sql语句中的参数 传到cursor.execute()中来pymysql会自动填充执行(注意后面的需要填充的参数用列表或者元素的形式) # sql="select * from userinfo where username=%(u)s and password=%(p)s" # 下面cursor.execute(sql,{"u":usm,"p":pwd}) 就得写成字典形式 # cursor.execute(sql,{"u":usm,"p":pwd}) result=cursor.fetchone() # select 数据库查询结果需要使用fetchone()来获得; cursor.close() # 关闭数据库 conn.close() # print(result) # 查看操作数据库(select查询结果,如果用户输入的用户名和密码在userinfo表中可以查找到,就证明该用户是合法用户,可以登录成功) if result: print("恭喜您,登陆成功") else: print("抱歉,登录失败!")
运行结果:
2. 使用pymysql模块实现python操作数据库---增删改查
2.1 增
import pymysql conn=pymysql.connect(host="localhost",user="root",password="******",database="db666") cursor=conn.cursor() sql="insert into userinfo(username,password) values('xixi','123')" # 往infor表中增加一条记录 cursor.execute(sql) # 使用cursor.execute()执行sql语句 conn.commit() # 将增加insert 数据项的操作提交!! 但是对数据库查询操作不需要提交 # cursor.fetchone() # 查询操作需要获得查询结果的返回值(对数据库增删改时不需要cursor.fetchone()获得一条记录,只需要提交操作即可) cursor.close() # 关闭数据库 conn.close()
运行结果:
增加数据的操作(带有变量的,跟之前查询带有变量一样,将需要传入的参数放在cursor.execute(sql,[args])中去)不要sql注入;
import pymysql conn=pymysql.connect(host="localhost",user="root",password="*******",database="db666") cursor=conn.cursor() sql="insert into userinfo(username,password)values(%s,%s)" # 注意当使用cursor.execute(sql,(arg1,arg2))往sql中传入参数时,一定要注意%s不要加引号!!! cursor.execute(sql,["dongdong","123"]) # cursor.execute()传入参数可以写成[] 或者()形式 conn.commit() cursor.close() conn.close()
运行结果:
当需要增加多条数据时:
import pymysql conn=pymysql.connect(host="localhost",user="root",password="******",database="db666") cursor=conn.cursor() sql="insert into userinfo(username,password) values(%s,%s)" # 当使用cursor.execute(sql,[arg1,arg2])传入参数时 sql语句中响应变量的占位符不要加引号!! cursor.executemany(sql,[['haha','123'],['nene','123'],['bobo','123']]) # 插入多条数据 要使用cursor.executemany(sql,[(),(),()]) 不是execute() 而是executemany()!!! conn.commit() # 当对数据库执行增删改操作时,一定要注意提交conn.commit() cursor.close() conn.close()
运行结果:
2.2 删 改操作(同增)都需要在cursor.execute(sql)之后进行提交conn.commit()
3. 查--fetchone() 差一条数据,fetchmany(n) 查多条数据 fetchall()查所有数据;
import pymysql conn=pymysql.connect(host="localhost",user="root",password="******",database="db666") cursor=conn.cursor() sql="select * from userinfo" cursor.execute(sql) result=cursor.fetchone() # fetchone()获得一条数据,查操作需要cursor.fetch() 但是不需要conn.commit() 增删改刚好反过来 print(result) result=cursor.fetchone() # 又拿到一条数据(会有一个指针移动的,拿到下一条数据) print(result) cursor.close() conn.close()
运行结果:
其实可以看到的cursor.fetchone()返回的结果是一个元祖类型的,但是看起来很不方便,所以我们可以使用cursor=conn.cursor(cursor=pymysql.cursors,DictCursor)修改conn.cursor()的参数,使得cursor.fetchone()返回的结果是一个字典(字段:字段对应的值)
import pymysql conn=pymysql.connect(host="localhost",user="root",password="******",database="db666") cursor=conn.cursor(cursor=pymysql.cursors.DictCursor) # 修改conn.cursor(cursor=)的参数,使得cursor.fetchone()返回的结果不再是元组 而是直观的字典形式 sql="select * from userinfo" cursor.execute(sql) result=cursor.fetchone() # fetchone()获得一条数据,查操作需要cursor.fetch() 但是不需要conn.commit() 增删改刚好反过来 print(result) result=cursor.fetchone() # 又拿到一条数据(会有一个指针移动的,拿到下一条数据) print(result) cursor.close() conn.close()
运行结果:
如果是获得多条数据时:可以使用cursor.fetchmany(n) 获得所有数据可以使用cursor.fetchall()
import pymysql conn=pymysql.connect(host="localhost",user="root",password="******",database="db666") cursor=conn.cursor(cursor=pymysql.cursors.DictCursor) # 修改conn.cursor(cursor=)的参数,使得cursor.fetchone()返回的结果不再是元组 而是直观的字典形式 sql="select * from userinfo" cursor.execute(sql) result=cursor.fetchmany(4) # fetchmany(4)获得查询结果的四条 print(result) cursor.close() conn.close()
运行结果:
import pymysql conn=pymysql.connect(host="localhost",user="root",password="***********",database="db666") cursor=conn.cursor(cursor=pymysql.cursors.DictCursor) # 修改conn.cursor(cursor=)的参数,使得cursor.fetchone()返回的结果不再是元组 而是直观的字典形式 sql="select * from userinfo" cursor.execute(sql) result=cursor.fetchall() # fetchall()获得所有的查询结果 print(result) cursor.close() conn.close()
4. 获得新插入数据的自增ID(cursor.lastrowid)
就是当一张表插入数据的字段比如userinfo表 只插入username,password 但是可能有时候需要获得新插入数据的uid(主键自增的id) 就需要使用cursor.lastrowid获得
import pymysql conn=pymysql.connect(host="localhost",user="root",password="123",database="db666") cursor=conn.cursor() # cursor=conn.cursor(cursor=pymysql.cursors.DictCursor)显示结果是字典形式 一般select查询时才会用到 sql="insert into userinfo(username,password) values(%s,%s)" cursor.execute(sql,["nono","124"]) conn.commit() # 对数据库执行增删改时需要提交 print(cursor.lastrowid) # 获得最新插入数据的自增ID cursor.close() conn.close()
运行结果: