python数据库驱动_python数据库驱动 --- pymysql

python中的mysql驱动(库)

python中封装了与mysql服务之间的通讯接口,从而实现在Python程序中简单方法调用就可以实现数据库操作。

连接数据库进行操作需要支持数据库和网络传输的大量协议,直接使用socket连接数据库并进行通信是相当复杂的,所以Python提供了访问数据库的接口,这些协议和复杂操作都被封装在底层的协议中,不用我们自己实现。

提供的驱动(库)

MySQLdb

这是较为底层的库,但是该库只支持Python2,但不能支持Python3且不再更新。

mysqlclient

在MySQLdb上,增加了Python3的支持

pymysql

语法兼容MySQLdb,使用纯Python写的MySQLdb客户端,支持Python2.7,3.4+,MySQL5.5+,MariaDB 5.5+

pymysql使用

使用pymysql连接某一个数据库,通过cursor方法获取一个游标,这样就可以直接使用这个游标执行sql语句,进行数据库的交互操作了。由于调用了数据库,注意异常捕获和最后的资源释放

基本使用

一般流程

建立连接

获取游标

执行SQL

提交事务(失败回滚)

释放资源

importpymysql

conn=Nonetry:

conn= pymysql.connect(host="127.0.0.1", user="root", password="root", databse="test", port=3306) #指定ip,端口,用户,密码,库等信息

cursor= conn.cursor() #指定一个游标,库中指定了部分cursor类型

n = cursor.execute("select * from table_name") #在execute方法中写入SQL语句,进行查询,返回服务端对应的操作的行数。并不是返回查询的结果。结果被保存在cursor中。

#获取查询的结果,使用fetchone, fetchall, fetchmany函数均可

cursor.fetchone() #从返回的结果集中返回一条

cursor.fetchall() #获取剩余的所有结果

cursor.fetchmany(3) #无法在获取,cursor位置已到最后

#cursor.rownumber 记录了当前cursor的位置,重置即可再次访问这些数据

cursor.rownumber = 0 #回到开始,该 数值正负都支持,超界不报错

exceptException as e:#记录错误日志

logging.error(e)ifconn:

conn.rollback()#事务中发生了错误,将执行的结果回滚。

finally:#关闭链接和cursor

cursor.close()ifconn:

conn.close()

可以同时在conn 上创建多个cursor 对象,这些cursor之间互不影响。

上下文管理器的使用

conn对象和cursor对象均可以使用with上下文管理器

conn

conn 是Connections.py 下的Connection 类实例,Connection 中的源码定义如下:

classConnection:def __enter__(self):

warnings.warn("Context manager API of Connection object is deprecated; Use conn.begin()",

DeprecationWarning)return self.cursor() #返回一个cursor

#执行提交或回滚

def __exit__(self, exc, value, traceback):ifexc:

self.rollback()else:

self.commit()

使用示例

conn = pymysql.connect(host="127.0.0.1", user="root", password="root", databse="test", port=3306)

with conn as cursor:

cursor.execute("update table_name set name='tom' where name='jerry'")#conn 的 enter 方法返回一个cursor 对象,exit将事务提交commit

conn 对象的上下文管理并不会将关闭这个连接,最后我们必须手动关闭这连接,避免系统资源浪费。

cursor

cursor上下文管理源码:

classCursor(object):def __enter__(self): #返回自身

returnselfdef __exit__(self, *exc_info): #结束时关闭这个 cursor

delexc_info

self.close()

cursor 的上下文管理结束时会自动关闭这个cursor。示例

importpymysql

conn=Nonetry:

conn= pymysql.connect(host="127.0.0.1", user="root", password="root", databse="test", port=3306)

with conn.cursor() as cursor:

n= cursor.execute("select * from table_name") 入。

cursor.fetchone()#查询一条数据

#退出with 自动关闭 cursor,即使报错

exceptException as e:#记录错误日志

logging.error(e)ifconn:

conn.rollback()#事务中发生了错误,将执行的结果回滚。

finally:#关闭链接和cursor

ifconn:

conn.close()

Dictcursor

使用默认 cursor 时,查询的数据是会以元组的形式返回,元组中只有数据信息,而没有字段名;而使用Dictcursor返回的数据以字典的形式返回

importpymysql

conn= pymysql.connect(host="127.0.0.1", user="root", password="root", databse="test", port=3306)

with conn.cursor(pymysql.cursors.Dictcursor) as cursor:

n= cursor.execute("select * from Person") 入。print(cursor.fetchone())======= 使用Dictcursor 输出得结果 ===={id:1, name:tom, age:18}======= 使用默认cursor的结果 =====(1, tom, age)

这样我们可以方便的在结果中获取字段名。

SQL注入

SQL注入攻击是猜测后台SQL语句使用的字符串拼接形式,从而经过专门的设计传参,拼接出一些特殊的,非本意的SQL语句在数据库执行,使攻击者获取想要的结果

例如查询数据库所有的数据

cmd = input(">>>")

cursor.execute("select * from name=`{}`".format(cmd))

上面用户可以输入名字获取查询的结果,例如我们可以输入tom,这样就会返回名为tom的person信息。根据这拼接字符串的规律,我们可以拼接出其他用途的SQL语句。输入tom or "1" = "1"进行查询,我们将获得这个表中的全部人员信息,这并不是我们希望的,这样我们的数据就被轻易获取了。

参数化查询

参数化查询(Parameterized Query 或 Parameterized Statement)是访问数据库时,在需要填入数值或数据的地方,使用参数 (Parameter) 来给值。

cmd = input(">>>")

cursor.execute("select * from name= %(name)s", {"name":cmd}) #使用字典映射#或者 cursor.execute("select * from name= %s", (name,)) 使用位置对应

使用这种方式拼接SQL时,将不会发生上面的现象

cmd = "10001 or '1'='1'"n= cursor.execute("select * from employees where emp_no=%s", (cmd, ))print(cursor.fetchall)====输出结果====((10001, datetime.date(1953, 9, 2), 'Georgi', 'Facello', 'M', datetime.date(1986, 6, 26)),) #返回的数据,只获取了一条数据

Warning: (1292, "Truncated incorrect DOUBLE value: '10001 or '1'='1''")

result= self._query(query) #显示的警告信息,程序检测出了这个字符串的"问题"

参数化查询已被视为最有效可预防SQL注入攻击 (SQL Injection) 的攻击手法的防御方式。在使用参数化查询的情况下,数据库服务器不会将参数的内容视为SQL指令的一部份来处理,而是在数据库完成SQL指令的编译后,才套用参数运行,因此就算参数中含有指令,也不会被数据库运行。Access、SQL Server、MySQL、SQLite等常用数据库都支持参数化查询。

参数化查询按还能减少sql语句的编译,较少资源的销号,在上面的程序中,使用参数化查询时,上面的字符串select * from employees where emp_no=%s将会被编译一次然后被缓存,缓存在未失效的情况不会重复对字符串进行编译,而如果直接使用sql语句字符串,每次都会对其编译,耗费不少资源。因此使用参数化查询几乎不会降低查询效率。

mysqlclient

通过mysqlclient也可以实现Python与数据库的连接,他们使用相同接口函数,其余用法基本相同

pip install mysqlclient

importMySQLdb

conn=Nonetry:

conn= MySQLdb.connect(host="127.0.0.1", user="root", password="root", databse="test", port=3306)

with conn.cursor() as cursor:

params= "10010"n= cursor.execute("select * from employees where id=%s", args=(params,))

res=cursor.fetchall()print(res)exceptException as e:print(e) #写入日志

finally:ifNone:

conn.close()#关闭连接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值