python连接操作mysql数据库使用详解

     在python3中,有个模块pymysql,用户可以通过这个模块实现远程对mysql数据库的操作。

1.python操作mysql流程架构

2 .python操作mysql使用演示

1.安装并且导入包pymysql,如果环境中没有安装pymysql包,可以直接pip3 install pymysql安装该模块,然后使用import pymysql查看是否安装正确。下面是基于pycharm进行开发测试python连接操作数据库

from pymysql import *

def main():
    # 创建Connection连接
    conn = connect(host='localhost',port=3306,database='jing_dong',user='root',password='123456',charset='utf8')
    # 获得Cursor对象
    cs1 = conn.cursor()
    # 执行insert语句,并返回受影响的行数:添加一条数据
    # 增加
    count = cs1.execute('insert into goods_cates(name) values("硬盘")')
    #打印受影响的行数
    print(count)

    count = cs1.execute('insert into goods_cates(name) values("光盘")')
    print(count)

    # # 更新
    # count = cs1.execute('update goods_cates set name="机械硬盘" where name="硬盘"')
    # # 删除
    # count = cs1.execute('delete from goods_cates where id=6')

    # 提交之前的操作,如果之前已经之执行过多次的execute,那么就都进行提交
    conn.commit()

    # 关闭Cursor对象
    cs1.close()
    # 关闭Connection对象
    conn.close()

if __name__ == '__main__':
    main()

尖叫提示: 

1.Connection 对象

   1.1用于建立与数据库的连接,创建对象:调用connect()方法,该方法有很多参数,可以参考源码。

   1.2该connect()常用参数如下:这些参数的顺序可以调整,不用一致。

  • 参数host:连接的mysql主机ip,如果本机是'localhost'
  • 参数port:连接的mysql主机的端口,默认是3306
  • 参数database:数据库的名称
  • 参数user:连接的用户名
  • 参数password:连接的密码
  • 参数charset:通信采用的编码方式,推荐使用utf8

   1.3 Connection对象的方法

  • close()关闭连接
  • commit()提交,主要用来对数据增,删,改操作后提交的。
  • cursor()返回Cursor对象,用于执行sql语句并获得结果

2.Cursor对象

  • 用于执行sql语句,使用频度最高的语句顺序为select、insert、update、delete
  • 获取Cursor对象:调用Connection对象的cursor()方法

2.1对象的方法

  • close()关闭
  • execute(operation [, parameters ])执行语句,返回受影响的行数,主要用于执行insert、update、delete语句,也可以执行create、alter、drop等语句
  • fetchone()执行查询语句时,获取查询结果集的第一个行数据,返回一个元组
  • fetchall()执行查询时,获取结果集的所有行,一行构成一个元组,再将这些元组装入一个元组返回
  • fetchmany( int args )执行查询时,获取查询结果集的指定几行,返回一个元组。

2.2对象的属性

  • rowcount只读属性,表示最近一次execute()执行后受影响的行数
  • connection获得当前连接对象

3.python操作mysql的注意事项

1.如下通过python查询mysql中多条数据

from pymysql import *

def main():
    # 创建Connection连接
    conn = connect(host='localhost',port=3306,user='root',password='123456',database='jing_dong',charset='utf8')
    # 获得Cursor对象
    cs1 = conn.cursor()
    # 执行select语句,并返回受影响的行数:查询一条数据
    count = cs1.execute('select id,name from goods where id>=4')
    # 打印受影响的行数
    print("查询到%d条数据:" % count)

    # for i in range(count):
    #     # 获取查询的结果
    #     result = cs1.fetchone()
    #     # 打印查询的结果
    #     print(result)
    #     # 获取查询的结果

    result = cs1.fetchall()
    print(result)

    # 关闭Cursor对象
    cs1.close()
    conn.close()

if __name__ == '__main__':
    main()
    
''''
查询到19条数据:
((4, 'x550cc 15.6英寸笔记本'), (5, 'x240 超极本'), (6, 'u330p 13.3英寸超极本'), (7, 'svp13226scb 触控超极本'), (8, 'ipad mini 7.9英寸平板电脑'), (9, 'ipad air 9.7英寸平板电脑'), (10, 'ipad mini 配备 retina 显示屏'), (11, 'ideacentre c340 20英寸一体电脑 '), (12, 'vostro 3800-r1206 台式电脑'), (13, 'imac me086ch/a 21.5英寸一体电脑'), (14, 'at7-7414lp 台式电脑 linux )'), (15, 'z220sff f4f06pa工作站'), (16, 'poweredge ii服务器'), (17, 'mac pro专业级台式电脑'), (18, 'hmz-t3w 头戴显示设备'), (19, '商务双肩背包'), (20, 'x3250 m4机架式服务器'), (21, '商务双肩背包'), (22, 'LaserJet Pro P1606dn 黑白激光打印机'))
Process finished with exit code 0

'''

2.如何防止sql注入 

下面演示什么叫sql注入,就是非法的sql输入来获取系统的一些使用权限。

from pymysql import *

def main():

    find_name = input("请输入物品名称:")

    # 创建Connection连接
    conn = connect(host='localhost',port=3306,user='root',password='123456',database='jing_dong',charset='utf8')
    # 获得Cursor对象
    cs1 = conn.cursor()

    # 输入 " or 1=1 or "   (双引号也要输入)
    sql = 'select * from goods where name="%s"' % find_name
    print("""sql===>%s<====""" % sql)

    count = cs1.execute(sql)

    # 打印受影响的行数
    print(count)
    # 获取查询的结果
    # result = cs1.fetchone()
    result = cs1.fetchall()
    # 打印查询的结果
    print(result)
    # 关闭Cursor对象
    cs1.close()
    # 关闭Connection对象
    conn.close()

if __name__ == '__main__':
    main()

执行上面程序,在输入商品时,我们输入" or 1=1 or "   (双引号也要输入),这样与我们底层写好的查询语句进行拼接,如下,拼接后的sql就变成了select * from goods where name="" or 1=1 or "",这是一个恒成立的where子句,所以可以获取该表中所有数据。

请输入物品名称:" or 1=1 or "
sql===>select * from goods where name="" or 1=1 or ""<====
22
((1, 'r510vc 15.6英寸笔记本', 5, 2, Decimal('3399.000'), b'\x01', b'\x00'), (2, 'y400n 14.0英寸笔记本电脑', 5, 7, Decimal('4999.000'), b'\x01', b'\x00'), (3, 'g150th 15.6英寸游戏本', 4, 9, Decimal('8499.000'), b'\x01', b'\x00'), (4, 'x550cc 15.6英寸笔记本', 5, 2, Decimal('2799.000'), b'\x01', b'\x00'), (5, 'x240 超极本', 7, 7, Decimal('4880.000'), b'\x01', b'\x00'), (6, 'u330p 13.3英寸超极本', 7, 7, Decimal('4299.000'), b'\x01', b'\x00'), (7, 'svp13226scb 触控超极本', 7, 6, Decimal('7999.000'), b'\x01', b'\x00'), (8, 'ipad mini 7.9英寸平板电脑', 2, 8, Decimal('1998.000'), b'\x01', b'\x00'), (9, 'ipad air 9.7英寸平板电脑', 2, 8, Decimal('3388.000'), b'\x01', b'\x00'), (10, 'ipad mini 配备 retina 显示屏', 2, 8, Decimal('2788.000'), b'\x01', b'\x00'), (11, 'ideacentre c340 20英寸一体电脑 ', 1, 7, Decimal('3499.000'), b'\x01', b'\x00'), (12, 'vostro 3800-r1206 台式电脑', 1, 5, Decimal('2899.000'), b'\x01', b'\x00'), (13, 'imac me086ch/a 21.5英寸一体电脑', 1, 8, Decimal('9188.000'), b'\x01', b'\x00'), (14, 'at7-7414lp 台式电脑 linux )', 1, 3, Decimal('3699.000'), b'\x01', b'\x00'), (15, 'z220sff f4f06pa工作站', 3, 4, Decimal('4288.000'), b'\x01', b'\x00'), (16, 'poweredge ii服务器', 3, 5, Decimal('5388.000'), b'\x01', b'\x00'), (17, 'mac pro专业级台式电脑', 3, 8, Decimal('28888.000'), b'\x01', b'\x00'), (18, 'hmz-t3w 头戴显示设备', 6, 6, Decimal('6999.000'), b'\x01', b'\x00'), (19, '商务双肩背包', 6, 6, Decimal('99.000'), b'\x01', b'\x00'), (20, 'x3250 m4机架式服务器', 3, 1, Decimal('6888.000'), b'\x01', b'\x00'), (21, '商务双肩背包', 6, 6, Decimal('99.000'), b'\x01', b'\x00'), (22, 'LaserJet Pro P1606dn 黑白激光打印机', 12, 4, Decimal('1849.000'), b'\x01', b'\x00'))

Process finished with exit code 0

当然,之所以有sql注入,还是我们在开发的时候相当于留下了“漏洞”,才让别人有机可乘。比如python操作mysql,实际开发中我们不要写这种拼接的形式,而是要将查询语句参数化,就可以避免sql注入了。因为execute(),实现了反sql注入功能。

from pymysql import *

def main():

    find_name = input("请输入物品名称:")

    # 创建Connection连接
    conn = connect(host='localhost',port=3306,user='root',password='123456',database='jing_dong',charset='utf8')
    # 获得Cursor对象
    cs1 = conn.cursor()


    # 安全的方式
    # 构造参数列表
    params = [find_name]
    # 执行select语句,并返回受影响的行数:查询所有数据
    count = cs1.execute('select * from goods where name=%s', params)
    # 注意:
    # 如果要是有多个参数,需要进行参数化
    # 那么params = [数值1, 数值2....],此时sql语句中有多个%s即可

    # 打印受影响的行数
    print(count)
    # 获取查询的结果
    # result = cs1.fetchone()
    result = cs1.fetchall()
    # 打印查询的结果
    print(result)
    # 关闭Cursor对象
    cs1.close()
    # 关闭Connection对象
    conn.close()

if __name__ == '__main__':
    main()

'''这个时候再用sql注入的方式进行sql注入,发现失败了
请输入物品名称:" or 1=1 or "
0
()
'''
发布了248 篇原创文章 · 获赞 1600 · 访问量 267万+

猜你喜欢

转载自blog.csdn.net/qq_26442553/article/details/96108475