python mysqldb pymysql_mysqldb与pymysql

之前一直用的python2.7版本,用到的是MySQLdb这个模块。然而又经常在资料中有看到连接mysql使用的是pymysql模块,于是就好奇这两个到底有什么不同?于是,对这两个模块进行比较,看看究竟有什么区别。最后发现,其实差别不大,使用方法上几乎相同。

¶MySQLdb与PyMySQL的相关介绍MySQLdb只支持py2.x版本,而pymysql支持2.7以及3.x版本

¶MySQLdb目前支持MySQL版本3.23 - 5.5 并且 Python版本2.4 - 2.7

安装命令 pip install MySQL-python

MySQLdb 是基于_mysql 的python简易包装器(官方文档中的用的是thin wapper,不知道这样翻译对不对),它能兼容 Python DB API interface (version 2)[PEP-0249],所以大部分使用方式还是根据[PEP-0249]定义。只有MySQLdb模块中与接口定义不同的时候,参考MySQLdb模块文档[MySQLdb]。其实MySQLdb只是定义了一些顶层的一些函数和属性,底层的很多东西在_mysql。_mysql 模块

如果要编写可跨数据库移植的应用,使用 MySQLdb模块而避免直接使用_mysql模块,因为我们使用MySQLdb模块基本上使用的是高级别的函数。_mysql 是基于实现MySQL C API的接口,更多内容参见 MySQL documentation。

所以第3点可以概括为,MySQLdb实现了 Python 数据库 API 规范 V2.0,基于 MySQL C API 上建立的。

¶PyMySQL安装环境python版本

CPython : 2.7 and >= 3.4

PyPy : Latest version

MySQL Server版本

MySQL >= 5.5

安装命令 pip install pymysql

pymysql是基于PEP 249 的纯python MySQL客户端库。大多数的API与mysqlclient 和MySQLdb兼容。注意的是,pymysql并不支持低级别的_mysql接口。

因此,pymysql基本可以代替MySQLdb,解决因为python版本带来的问题。

¶含有格式化操作符的sql语句的执行

由于含有格式化操作符的sql语句经常出现各种写法,因此这里做一个总结。下面我们先建立链接,进而创建一个table。1

2

3

4

5

6

7

8

9import MySQLdb

conn = MySQLdb.connect(host='localhost',

user = 'root',

passwd ='',

db = 'user_information',

charset='utf8')

#实参均是字符串形式

cursor = conn.cursor()1

2

3

4

5

6

7import pymysql

connection = pymysql.connect(host='localhost',

user='root',

password='',

db='db',

charset='utf8')

cursor = conn.cursor()

这里我们写出两个模块的connect()操作,可以发现,MySQLdb密码的参数名是passwd。这个自己写的时候容易出错。稍微提一下哈。

然后我们在连接上创建数据表,如下:1

2

3

4

5

6

7

8

9

10

11def ():

sql = """CREATE TABLE client(

client_id int auto_increment,

name varchar(20),

age int,

phone char(11),

PRIMARY KEY(client_id)

)

"""

cursor.execute(sql)

#后面的操作均在本表的基础上进行

以上都是铺垫,下面才正式进入sql语句的执行部分。

如果我们经常Ctrl C + V的话,基本很难发现这个小细节。因为这跟字符串匹配有点类似。如果不参照各种模板,基本上按照字符串匹配符和参数的写法写的。我自己写出来的sql语句就是这样的:1

2

3sql = "INSERT INTO client(name,age,phone)

VALUES(%s,%d,%s)" % ('converse', 27 ,'12345654321')

cursor.execute(sql)

。。很显然,这就心塞的报错了。(不就是一个插入语句么,怎么就会错?目前问题出现的原因不详。)

使用mysqldb模块:

使用pymysql模块:

就说一下该情况出现的解决方式吧。

​其实百度一下也很容易解决,用 ’ ’ 将字符串格式化操作符包裹起来就正确了。那么含有字符串格式化操作符的sql语句的格式该如何进行书写?下面进行总结。(不论使用哪个模块,均可采用以下两种方式执行含有字符串格式化操作符的sql语句,因此是通用的不区分模块进行书写)

执行含有字符串格式化操作符的sql语句有以下两种方式:

¶sql语句的拼接方式采用%1

2

3sql = "INSERT INTO client(name,age,phone)

VALUES('%s','%d','%s')" % ('converse', 27 ,'12345654321')

cursor.execute(sql)

可以看到,格式化操作符如:%d,%s均被 ’ '包裹起来变成 ‘%d’, ‘%s’。

采用 .format()1

2

3sql = "INSERT INTO client(name,age,phone)

VALUES('{0}','{1}','{2}')".format('converse', 27 ,'12345654321')

cursor.execute(sql)

可以看到,如:{0}, {1}均被 ’ '包裹起来变成 ‘{0}’, ‘{1}’。

在执行,可以看到,数据被成功插入到数据表中。然而后面可以验证,这种方式是存在SQL注入的隐患。

¶sql语句的传参方式1

2sql = "INSERT INTO client(name,age,phone) VALUES (%s, %d, %s)"

cursor.execute(sql,('converse', 27 ,'12345654321'))

这种方式是以参数传递的方式先组合sql语句再执行组合后的sql。在官方的pymysql模块例子中,sql语句执行也是采用传参的方式,可以点击查看demo。

¶防SQL注入sql注入原理就是用户输入动态的构造了意外sql语句,造成了意外结果,是攻击者有机可乘。

下面我们在pymysql模块中进行操作,两种sql方式之间的差别。拼接方式

首先定义一个查询函数如下:1

2

3

4

5

6

7

8def select_data_Withcatch():

#方式1:拼接方式

sql = "SELECT name,age,phone FROM client where name = '%s'"%("'or1='1")

res = cursor.execute(sql)#返回的是结果集的数目

print res

results = cursor.fetchall()#返回所有结果

for i in results:

print i

通过拼接后的sql语句可以表示为:1sql = "SELECT name,age,phone FROM client where name = ''or1= '1'"

由于1='1’总是为真,所以sql等价于select name,age,phone from client,因此该函数的执行结果如下,返回表中所有数据信息。

传参方式1

2

3

4

5

6

7

8

9

10

11def select_data_withParameters():

#方式2 传入参数方式

sql = "SELECT name,age,phone FROM client where name = %s"

res = cursor.execute(sql, "'or'1")

print cursor.mogrify(sql, "'or'1")

#内部执行参数化生成的SQL语句,对特殊字符进行了加转义,避免注入语句生成。打印出来实际对MYSQL执行的sql语句

print res

results = cursor.fetchall()

print results

for i in results:

print i

我们先看执行结果,同样的输入,采用传参方法可以避免SQL注入。

因为,通过参数生成SQL语句对特殊字符进行了加转义,避免注入语句生成。其中cursor.mogrify()打印出来的是实际对数据库进行操作的SQL语句。该方法能够返回调用execute()方法真正操作数据库的SQL语句。

该方法只存在于pymysql模块中。

以上就是两个模块的总结,以及经常执行sql语句的两种方式总结。以后就知道什么时候带 ’‘ 什么时候不带 ’‘。再也不搞混了。

总结:pymysql更好,不存在Python版本问题,用法兼容MySQLdb

含有字符串格式化操作符的sql语句,采用传参方式更安全

参考链接:

[在使用pymysql对mysql进行操作时,使用%s给excute传入参数时出错]----> https://www.jianshu.com/p/855fdb50c26c

你可能感兴趣的:(python,mysqldb,pymysql)