Python之pymysql的使用小结
在python3.x中,可以使用pymysql来MySQL数据库的连接,并实现数据库的各种操作,本次博客主要介绍了pymysql的安装和使用方法。
PyMySQL的安装
一、.windows上的安装方法:
在python3.6中,自带pip3,所以在python3中可以直接使用pip3去安装所需的模块:
pip3installpymysql-ihttps://pypi.douban.com/simple
二、.linux下安装方法:
1.tar包下载及解压
下载tar包 wgethttps://pypi.python.org/packages/29/f8/919a28976bf0557b7819fd6935bfd839118aff913407ca58346e14fa6c86/PyMySQL-0.7.11.tar.gz#md5=167f28514f4c20cbc6b1ddf831ade772 解压并展开tar包 tarxfPyMySQL-0.7.11.tar.gz
2.安装
[root@localhostPyMySQL-0.7.11]#python36setup.pyinstall
数据库的连接
本次测试创建的数据及表:
#创建数据库及表,然后插入数据
mysql>createdatabasedbforpymysql;
mysql>createtableuserinfo(idintnotnullauto_incrementprimarykey,usernamevarchar(10),passwdvarchar(10))engine=innodbdefaultcharset=utf8;
mysql>insertintouserinfo(username,passwd)values('frank','123'),('rose','321'),('jeff',666);
#查看表内容
mysql>select*fromuserinfo;
+----+----------+--------+
|id|username|passwd|
+----+----------+--------+
|1|frank|123|
|2|rose|321|
|3|jeff|666|
+----+----------+--------+
3rowsinset(0.00sec)
连接数据库:
importpymysql
#连接数据库
db=pymysql.connect("localhost","root","LBLB1212@@","dbforpymysql")
#使用cursor()方法创建一个游标对象
cursor=db.cursor()
#使用execute()方法执行SQL语句
cursor.execute("SELECT*FROMuserinfo")
#使用fetall()获取全部数据
data=cursor.fetchall()
#打印获取到的数据
print(data)
#关闭游标和数据库的连接
cursor.close()
db.close()
#运行结果
((1,'frank','123'),(2,'rose','321'),(3,'jeff','666'))
要完成一个MySQL数据的连接,在connect中可以接受以下参数:
def__init__(self,host=None,user=None,password="",
database=None,port=0,unix_socket=None,
charset='',sql_mode=None,
read_default_file=None,conv=None,use_unicode=None,
client_flag=0,cursorclass=Cursor,init_command=None,
connect_timeout=10,ssl=None,read_default_group=None,
compress=None,named_pipe=None,no_delay=None,
autocommit=False,db=None,passwd=None,local_infile=False,
max_allowed_packet=16*1024*1024,defer_connect=False,
auth_plugin_map={},read_timeout=None,write_timeout=None,
bind_address=None):
参数解释:
host:Hostwherethedatabaseserverislocated#主机名或者主机地址
user:Usernametologinas#用户名
password:Passwordtouse.#密码
database:Databasetouse,Nonetonotuseaparticularone.#指定的数据库
port:MySQLporttouse,defaultisusuallyOK.(default:3306)#端口,默认是3306
bind_address:Whentheclienthasmultiplenetworkinterfaces,specify
theinterfacefromwhichtoconnecttothehost.Argumentcanbe
ahostnameoranIPaddress.#当客户端有多个网络接口的时候,指点连接到数据库的接口,可以是一个主机名或者ip地址
unix_socket:Optionally,youcanuseaunixsocketratherthanTCP/IP.
charset:Charsetyouwanttouse.#指定字符编码
sql_mode:DefaultSQL_MODEtouse.
read_default_file:
Specifiesmy.cnffiletoreadtheseparametersfromunderthe[client]section.
conv:
Conversiondictionarytouseinsteadofthedefaultone.
Thisisusedtoprovidecustommarshallingandunmarshalingoftypes.
Seeconverters.
use_unicode:
Whetherornottodefaulttounicodestrings.
ThisoptiondefaultstotrueforPy3k.
client_flag:CustomflagstosendtoMySQL.Findpotentialvaluesinconstants.CLIENT.
cursorclass:Customcursorclasstouse.
init_command:InitialSQLstatementtorunwhenconnectionisestablished.
connect_timeout:Timeoutbeforethrowinganexceptionwhenconnecting.
(default:10,min:1,max:31536000)
ssl:
Adictofargumentssimilartomysql_ssl_set()'sparameters.
Fornowthecapathandcipherargumentsarenotsupported.
read_default_group:Grouptoreadfromintheconfigurationfile.
compress;Notsupported
named_pipe:Notsupported
autocommit:Autocommitmode.Nonemeansuseserverdefault.(default:False)
local_infile:BooleantoenabletheuseofLOADDATALOCALcommand.(default:False)
max_allowed_packet:Maxsizeofpacketsenttoserverinbytes.(default:16MB)
Onlyusedtolimitsizeof"LOADLOCALINFILE"datapacketsmallerthandefault(16KB).
defer_connect:Don'texplicitlyconnectoncontruction-waitforconnectcall.
(default:False)
auth_plugin_map:Adictofpluginnamestoaclassthatprocessesthatplugin.
TheclasswilltaketheConnectionobjectastheargumenttotheconstructor.
Theclassneedsanauthenticatemethodtakinganauthenticationpacketas
anargument.Forthedialogplugin,aprompt(echo,prompt)methodcanbeused
(ifnoauthenticatemethod)forreturningastringfromtheuser.(experimental)
db:Aliasfordatabase.(forcompatibilitytoMySQLdb)
passwd:Aliasforpassword.(forcompatibilitytoMySQLdb)
cursor其实是调用了cursors模块下的Cursor的类,这个模块主要的作用就是用来和数据库交互的,当你实例化了一个对象的时候,你就可以调用对象下面的各种绑定方法:
classCursor(object): """ Thisistheobjectyouusetointeractwiththedatabase. """ defclose(self): """ Closingacursorjustexhaustsallremainingdata. """ defsetinputsizes(self,*args): """Doesnothing,requiredbyDBAPI.""" defsetoutputsizes(self,*args): """Doesnothing,requiredbyDBAPI.""" defexecute(self,query,args=None): """Executeaquery :paramstrquery:Querytoexecute. :paramargs:parametersusedwithquery.(optional) :typeargs:tuple,listordict :return:Numberofaffectedrows :rtype:int Ifargsisalistortuple,%scanbeusedasaplaceholderinthequery. Ifargsisadict,%(name)scanbeusedasaplaceholderinthequery. """ defexecutemany(self,query,args): #type:(str,list)->int """Runseveraldataagainstonequery :paramquery:querytoexecuteonserver :paramargs:Sequenceofsequencesormappings.Itisusedasparameter. :return:Numberofrowsaffected,ifany. Thismethodimprovesperformanceonmultiple-rowINSERTand REPLACE.Otherwiseitisequivalenttoloopingoverargswith execute(). """ deffetchone(self): """Fetchthenextrow""" deffetchmany(self,size=None): """Fetchseveralrows""" deffetchall(self): """Fetchalltherows""" ......
数据库操作
一、数据库增删改操作
commit()方法:在数据库里增、删、改的时候,必须要进行提交,否则插入的数据不生效。
importpymysql
config={
"host":"127.0.0.1",
"user":"root",
"password":"LBLB1212@@",
"database":"dbforpymysql"
}
db=pymysql.connect(**config)
cursor=db.cursor()
sql="INSERTINTOuserinfo(username,passwd)VALUES('jack','123')"
cursor.execute(sql)
db.commit()#提交数据
cursor.close()
db.close()
或者在execute提供插入的数据
importpymysql
config={
"host":"127.0.0.1",
"user":"root",
"password":"LBLB1212@@",
"database":"dbforpymysql"
}
db=pymysql.connect(**config)
cursor=db.cursor()
sql="INSERTINTOuserinfo(username,passwd)VALUES(%s,%s)"
cursor.execute(sql,("bob","123"))
db.commit()#提交数据
cursor.close()
db.close()
小知识点,mysql的注入问题:
在mysql中使用"--"代表注释,比如现在来实现一个用户登录的小程序:
用户名和密码都存在表userinfo中,表内容如下:
mysql>select*fromuserinfo;
+----+----------+--------+
|id|username|passwd|
+----+----------+--------+
|1|frank|123|
|2|rose|321|
|3|jeff|666|
+----+----------+--------+
3rowsinset(0.00sec)
小程序代码如下:
importpymysql
user=input("username:")
pwd=input("password:")
config={
"host":"127.0.0.1",
"user":"root",
"password":"LBLB1212@@",
"database":"dbforpymysql"
}
db=pymysql.connect(**config)
cursor=db.cursor(cursor=pymysql.cursors.DictCursor)
sql="select*fromuserinfowhereusername='%s'andpasswd='%s'"%(user,pwd)
result=cursor.execute(sql)
cursor.close()
db.close()
ifresult:
print('登录成功')
else:
print('登录失败')
#正确登录的运行结果
username:frank
password:123
result:1
登录成功
#错误登录的运行结果
username:frank
password:1231231
result:0
登录失败
看起来没有什么问题,但是试试下面的方式吧
----------------------------------------------
username:'or1=1--
password:123
result:3
登录成功
----------------------------------------------
咦~也登录成功了.
为什么呢?可以看一下现在的执行的sql语句:
select*fromuserinfowhereusername=''or1=1--'andpasswd='123'
这里--后面的会被注释,所以where一定会成功,这里等于查看了所有行的内容,返回值也不等于0,所以就登录成功了。
解决方法就是将变量或者实参直接写到execute中即可:
result=cursor.execute(sql,(user,pwd))
在键入类似'or1=1--的时候就不会登录成功了。
executemany():用来同时插入多条数据:
importpymysql
config={
"host":"127.0.0.1",
"user":"root",
"password":"LBLB1212@@",
"database":"dbforpymysql"
}
db=pymysql.connect(**config)
cursor=db.cursor()
sql="INSERTINTOuserinfo(username,passwd)VALUES(%s,%s)"
cursor.executemany(sql,[("tom","123"),("alex",'321')])
db.commit()#提交数据
cursor.close()
db.close()
execute()和executemany()都会返回受影响的行数:
sql="deletefromuserinfowhereusername=%s"
res=cursor.executemany(sql,("jack",))
print("res=",res)
#运行结果
res=1
当表中有自增的主键的时候,可以使用lastrowid来获取最后一次自增的ID:
importpymysql
config={
"host":"127.0.0.1",
"user":"root",
"password":"LBLB1212@@",
"database":"dbforpymysql"
}
db=pymysql.connect(**config)
cursor=db.cursor()
sql="INSERTINTOuserinfo(username,passwd)VALUES(%s,%s)"
cursor.execute(sql,("zed","123"))
print("thelastrowidis",cursor.lastrowid)
db.commit()#提交数据
cursor.close()
db.close()
#运行结果
thelastrowidis10
二、数据库的查询操作
这里主要介绍三个绑定方法:
- fetchone():获取下一行数据,第一次为首行;
- fetchall():获取所有行数据源
- fetchmany(4):获取下4行数据
先来查看表的内容:
mysql>select*fromuserinfo; +----+----------+--------+ |id|username|passwd| +----+----------+--------+ |1|frank|123| |2|rose|321| |3|jeff|666| |5|bob|123| |8|jack|123| |10|zed|123| +----+----------+--------+ 6rowsinset(0.00sec)
使用fetchone():
importpymysql
config={
"host":"127.0.0.1",
"user":"root",
"password":"LBLB1212@@",
"database":"dbforpymysql"
}
db=pymysql.connect(**config)
cursor=db.cursor()
sql="SELECT*FROMuserinfo"
cursor.execute(sql)
res=cursor.fetchone()#第一次执行
print(res)
res=cursor.fetchone()#第二次执行
print(res)
cursor.close()
db.close()
#运行结果
(1,'frank','123')
(2,'rose','321')
使用fetchall():
importpymysql
config={
"host":"127.0.0.1",
"user":"root",
"password":"LBLB1212@@",
"database":"dbforpymysql"
}
db=pymysql.connect(**config)
cursor=db.cursor()
sql="SELECT*FROMuserinfo"
cursor.execute(sql)
res=cursor.fetchall()#第一次执行
print(res)
res=cursor.fetchall()#第二次执行
print(res)
cursor.close()
db.close()
#运行结果
((1,'frank','123'),(2,'rose','321'),(3,'jeff','666'),(5,'bob','123'),(8,'jack','123'),(10,'zed','123'))
()
可以看到,第二次获取的时候,什么数据都没有获取到,这个类似于文件的读取操作。
默认情况下,我们获取到的返回值是元组,只能看到每行的数据,却不知道每一列代表的是什么,这个时候可以使用以下方式来返回字典,每一行的数据都会生成一个字典:
cursor=db.cursor(cursor=pymysql.cursors.DictCursor)#在实例化的时候,将属性cursor设置为pymysql.cursors.DictCursor
使用fetchall获取所有行的数据,每一行都被生成一个字典放在列表里面:
importpymysql
config={
"host":"127.0.0.1",
"user":"root",
"password":"LBLB1212@@",
"database":"dbforpymysql"
}
db=pymysql.connect(**config)
cursor=db.cursor(cursor=pymysql.cursors.DictCursor)
sql="SELECT*FROMuserinfo"
cursor.execute(sql)
res=cursor.fetchall()
print(res)
cursor.close()
db.close()
#运行结果
[{'id':1,'username':'frank','passwd':'123'},{'id':2,'username':'rose','passwd':'321'},{'id':3,'username':'jeff','passwd':'666'},{'id':5,'username':'bob','passwd':'123'},{'id':8,'username':'jack','passwd':'123'},{'id':10,'username':'zed','passwd':'123'}]
这样获取到的内容就能够容易被理解和使用了!
在获取行数据的时候,可以理解开始的时候,有一个行指针指着第一行的上方,获取一行,它就向下移动一行,所以当行指针到最后一行的时候,就不能再获取到行的内容,所以我们可以使用如下方法来移动行指针:
cursor.scroll(1,mode='relative')#相对当前位置移动 cursor.scroll(2,mode='absolute')#相对绝对位置移动
第一个值为移动的行数,整数为向下移动,负数为向上移动,mode指定了是相对当前位置移动,还是相对于首行移动
例如:
sql="SELECT*FROMuserinfo"
cursor.execute(sql)
res=cursor.fetchall()
print(res)
cursor.scroll(0,mode='absolute')#相对首行移动了0,就是把行指针移动到了首行
res=cursor.fetchall()#第二次获取到的内容
print(res)
#运行结果
[{'id':1,'username':'frank','passwd':'123'},{'id':2,'username':'rose','passwd':'321'},{'id':3,'username':'jeff','passwd':'666'},{'id':5,'username':'bob','passwd':'123'},{'id':8,'username':'jack','passwd':'123'},{'id':10,'username':'zed','passwd':'123'}]
[{'id':1,'username':'frank','passwd':'123'},{'id':2,'username':'rose','passwd':'321'},{'id':3,'username':'jeff','passwd':'666'},{'id':5,'username':'bob','passwd':'123'},{'id':8,'username':'jack','passwd':'123'},{'id':10,'username':'zed','passwd':'123'}]
上下文管理器
在python的文件操作中支持上下文管理器,在操作数据库的时候也可以使用:
importpymysql
config={
"host":"127.0.0.1",
"user":"root",
"password":"LBLB1212@@",
"database":"dbforpymysql"
}
db=pymysql.connect(**config)
withdb.cursor(cursor=pymysql.cursors.DictCursor)ascursor:#获取数据库连接的对象
sql="SELECT*FROMuserinfo"
cursor.execute(sql)
res=cursor.fetchone()
print(res)
cursor.scroll(2,mode='relative')
res=cursor.fetchone()
print(res)
cursor.close()
db.close()
#运行结果
{'id':1,'username':'frank','passwd':'123'}
{'id':5,'username':'bob','passwd':'123'}
上下文管理器可以使代码的可读性更强。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。