进击のpython

*****

数据库——pymysql


数据库就算是学习完毕了,但是我们学习数据库的本质是什么?

是想让数据库像文件存储一样将信息存储起来供我们调用

那回归本行,我就应该是用python来处理数据库的相关操作

所以从这节开始就开始python跟数据库建立联系了

pymysql是一个第三方库,是用来使用Python语句来操作mysql的库

本质上就是个套接字连接

因为是第三方库,所以要安装~

我们用一个实例来带领你学习如何使用这个数据库


验证账号密码

验证之前得有一个数据库存放账号密码,所以先用上一节的可视化工具建立一个

创建完之后打开编译工具,调用pymysql:

import pymysql

因为他也相当于是套接字连接,所以首先应该建立联系,那都应该写什么呢?

pymysql.connect(
host='localhost', # ip
port=3306, # 端口
user='root', # 用户名
passwd='', # 密码
db='db10', # 连接的数据库
charset='utf8' # 编码方式
)

然后我们就要拿到游标,游标是什么呢?你注意到每次输入mysql语句的时候,都是 mysql>_

那这个_就是游标,我们输入SQL语句的手也是在这上面输入的,所以要先拿到游标:

cursor = conn.cursor()

我们是要验证账号密码,所以应该先输入再对比:

user = input('请输入用户名:').strip()
pwd = input('请输入密码:').strip()
sql='select * from user_info where name="%s" and pwd="%s"' %(user,pwd)

那执行给谁执行?游标!

rows = cursor.execute(sql)

这个拿到的结果是受影响的行数~也就是前几节命令执行完的最后一句话:3 rows in set (0.01 sec)

其实你想想,如果有行数改变,是不是就说明查找到了呢!

那执行完之后要把数据库关掉

cursor.close()
conn.close()

接下来就开始判断了:

if rows:
print('登陆成功!')
else:
print('登陆失败!')

完整代码:

import pymysql

user = input('请输入用户名:').strip()
pwd = input('请输入密码:').strip() conn = pymysql.connect(
host='localhost', # ip
port=3306, # 端口
user='root', # 用户名
password='', # 密码
db='db10', # 连接的数据库
charset='utf8' # 编码方式
) cursor = conn.cursor()
sql = 'select * from user_info where name="%s" and pwd="%s"' % (user, pwd)
rows = cursor.execute(sql)
cursor.close()
conn.close() if rows:
print('登陆成功!')
else:
print('登陆失败!')

SQL注入

来,先不用管这个SQL注入是什么,我来让你看一个现象

其实刚才咱们的代码有致命的漏洞,不信你看

很明显,这也登陆成功了!为什么呢???

那我是不是把账号密码都输入到sql里面了,我现在打印一下,看看是什么:

select * from user_info where name="apple" -- dawdwa" and pwd=""

注意!!!在sql语句中,杠杠空格后面的语句就是注释掉了!

所以实际上你只执行到了这句话

select * from user_info where name="apple"

当然就成功登录了!

好!那又有疑问了!那我这么写的前提是我得知道用户名,不知道也是登不上去的啊,所以不算致命漏洞

那你看这个!

卧槽!也成功了!这是不是就瞬间慌了!

是不是实际上执行的是

select * from user_info where name="xxx " or 1=1

问题是不是就严重起来了????其实这种情况就是sql注入!!!!

如何解决呢??其实很好解决,只要不让它输入这种非法字符就行了!

其实你也就知道了为什么有的网站在创建用户名的时候不让用特殊符号了

那如何才能检测用户输入的特殊字符呢??

pymysql的模块作者想到了这一点,然后就给你提供了execute来过滤掉这些非法字符

所以部分代码应该这样修改:

sql = 'select * from user_info where name=%s and pwd=%s'
rows = cursor.execute(sql, (user, pwd))

pymysql的增删改查

增 删 改

之所以把这三个放在一起,本质上都是对库进行了修改,所以放在一起,讲一个就能举一反三

sql = 'insert into user_info(name,pwd) values (%s,%s)'
rows = cursor.execute(sql, ("orange", "147258"))

到这就出现问题了,实际上,这么写不会真的修改数据库,如果你真的想改,就要在

conn.close()前面加上conn.commit(),加个提交才可以!

执行完之后用可视化工具看一眼吧~

但是我这样只能添加一个,我想一次添加多个怎么办呢??

那就要用到executemany方法了,列表里包裹的一个元祖就是一组数据

rows = cursor.executemany(sql, [("pear", "147258"), ('peach', '789456')])

最后再用可视化工具看一下,看看添没添加成功

这两面来回很麻烦,有没有能让结果在编译器里打印的呢?

有!一共有三个方法:

cursor.fetchall() # 拿出所有
cursor.fetchone() # 拿到一条数据,相当于把结果放进管道一个一个拿出来
cursor.fetchmany() # 指定取多少条

但是我拿到的只有数据,要是能加上字段就好了~

所以!字典就变成首选,那如何能让返回的数据变成字典呢?

我们可以在设置游标的时候设置:

cursor = conn.cursor(pymysql.cursors.DictCursor)

这是啥意思啊,是不是基于字典的游标啊,这回你再查:

print(cursor.fetchone())
print(cursor.fetchone())
print(cursor.fetchone())
{'id': 1, 'name': 'apple', 'pwd': '123456'}
{'id': 2, 'name': 'banana', 'pwd': '654321'}
{'id': 3, 'name': 'orange', 'pwd': '147258'}

是不是就是带有字段的了~

print(cursor.fetchmany(3))
[{'id': 1, 'name': 'apple', 'pwd': '123456'}, {'id': 2, 'name': 'banana', 'pwd': '654321'}, {'id': 3, 'name': 'orange', 'pwd': '147258'}]
print(cursor.fetchall())
[{'id': 1, 'name': 'apple', 'pwd': '123456'}, {'id': 2, 'name': 'banana', 'pwd': '654321'}, {'id': 3, 'name': 'orange', 'pwd': '147258'}, {'id': 4, 'name': 'pear', 'pwd': '147258'}, {'id': 5, 'name': 'peach', 'pwd': '789456'}]

那有的同学发现我featchall()了之后,再featchall()就会返回一个空列表

那我不想这样,我就想每一次featchall,都是完整打印,怎么办呢?

其实这就有点像文件操作的时候通过光标的移动来决定打印内容

在数据库这里就是通过游标位置来决定打印内容,对于游标的移动有两种方式

绝对移动:cursor.scroll(3,mode='absolute')

相对移动:cursor.scroll(3,mode='relative')

绝对移动就是从头开始移动几个:

cursor.scroll(3,mode='absolute')
print(cursor.fetchone())
{'id': 4, 'name': 'pear', 'pwd': '147258'}

相对移动就是根据当前的游标位置进行移动

print(cursor.fetchone())
cursor.scroll(2, mode='relative')
print(cursor.fetchone())
{'id': 1, 'name': 'apple', 'pwd': '123456'}
{'id': 4, 'name': 'pear', 'pwd': '147258'}

最后说一点,pymysql提供了一种方法,能够让你知道现在id走到哪了,在插入数据的时候可以使用

sql = 'insert into user_info(name,pwd) values (%s,%s)'
rows = cursor.execute(sql,('plum',888888)) print(cursor.lastrowid)

代表着id要从6开始,也代表着,plum这个数据的id是6!


*****
*****

数据库(十二):pymysql的更多相关文章

  1. 一、数据库表中字段的增删改查,二、路由基础.三、有名无名分组.四、多app共存的路由分配.五、多app共存时模板冲突问题.六、创建app流程.七、路由分发.八、路由别名,九、名称空间.十、反向解析.十一、2.x新特性.十二、自定义转换器

    一.数据库表中字段的增删改查 ''' 直接在modules中对字段进行增删改查 然后在tools下点击Run manage.py Task执行makemigrations和migrate 注意在执行字 ...

  2. m_Orchestrate learning system---三十二、数据库字段判断为空时容易出现问题,如何从根本上解决这个问题

    m_Orchestrate learning system---三十二.数据库字段判断为空时容易出现问题,如何从根本上解决这个问题 一.总结 一句话总结:字段禁止为空,设置默认值0即可 禁止 空 默认 ...

  3. OpenJDK源码研究笔记(十二):JDBC中的元数据,数据库元数据(DatabaseMetaData),参数元数据(ParameterMetaData),结果集元数据(ResultSetMetaDa

    元数据最本质.最抽象的定义为:data about data (关于数据的数据).它是一种广泛存在的现象,在许多领域有其具体的定义和应用. JDBC中的元数据,有数据库元数据(DatabaseMeta ...

  4. (十二)数据库查询处理之Query Execution(1)

    (十二)数据库查询处理之Query Execution(1) 1. 写在前面 这一大部分就是为了Lab3做准备的 每一个query plan都要实现一个next函数和一个init函数 对于next函数 ...

  5. 进击的Python【第十二章】:mysql介绍与简单操作,sqlachemy介绍与简单应用

    进击的Python[第十二章]:mysql介绍与简单操作,sqlachemy介绍与简单应用 一.数据库介绍 什么是数据库? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,每个数 ...

  6. python自动华 (十二)

    Python自动化 [第十二篇]:Python进阶-MySQL和ORM 本节内容 数据库介绍 mysql 数据库安装使用 mysql管理 mysql 数据类型 常用mysql命令 创建数据库 外键 增 ...

  7. Flask 教程 第二十二章:后台作业

    本文翻译自The Flask Mega-Tutorial Part XXII: Background Jobs 这是Flask Mega-Tutorial系列的第二十二部分,我将告诉你如何创建独立于W ...

  8. CRL快速开发框架系列教程十二(MongoDB支持)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  9. 我的MYSQL学习心得(十二) 触发器

    我的MYSQL学习心得(十二) 触发器 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数 ...

  10. 无废话ExtJs 入门教程十二[下拉列表联动:Combobox_Two]

    无废话ExtJs 入门教程十二[下拉列表联动:Combobox_Two] extjs技术交流,欢迎加群(201926085) 不管是几级下拉列表的联动实现本质上都是根据某个下拉列表的变化,去动态加载其 ...

随机推荐

  1. typeof、instanceof与constructor

    typeof返回一个表达式的数据类型的字符串,返回结果为js基本的数据类型,包括number,boolean,string,object,undefined,function. 语法: typeof( ...

  2. JavaScript基础对象创建模式之私有属性和方法(024)

    JavaScript没有特殊的语法来表示对象的私有属性和方法,默认的情况下,所有的属性和方法都是公有的.如下面用字面声明的对象: var myobj = { myprop: 1, getProp: f ...

  3. Python之浅谈函数

    目录 文件的高级应用 文件修改的两种方式 第一种 第二种 函数的定义 函数的参数 函数的返回值 文件的高级应用 r+即可读又可写,并且是在后面追加 w+清空文件的功能是w提供的 a+a有追加的功能,a ...

  4. day44 初识数据库

    目录 一.数据的演变 二.数据库 三.MySQL 1 基本原理 2 重要概念介绍 3 安装 4 启动 5 sql基本语句 6 环境变量的配置及系统服务制作 7 关于密码 8 统一编码 9 基本sql语 ...

  5. mui点击蒙版点击蒙版让其不自动关闭

    var mask = mui.createMask(callback);//callback为用户点击蒙版时自动执行的回调: mask.show();//显示遮罩 mask.close();//关闭遮 ...

  6. 基于html5拖拽api实现列表的拖拽排序

    基于html5拖拽api实现列表的拖拽排序 html代码: <ul ondrop="drop_handler(event);" ondragover="dragov ...

  7. Linux系统中到底应该怎么理解系统的平均负载

    02 | 基础篇:到底应该怎么理解“平均负载”? 每次发现系统变慢时,我们通常做的第一件事,就是执行 top 或者 uptime 命令,来了解系统的负载情况.比如像下面这样,我在命令行里输入了 upt ...

  8. java 面向对象(二十六):枚举类的使用

    1. 枚举类的说明:* 1.枚举类的理解:类的对象只有有限个,确定的.我们称此类为枚举类* 2.当需要定义一组常量时,强烈建议使用枚举类* 3.如果枚举类中只一个对象,则可以作为单例模式的实现方式. ...

  9. 数据可视化之powerBI入门 (一)认识PowerBI

    来自  https://zhuanlan.zhihu.com/p/64144024 Power BI是什么? Power BI是微软推出的数据分析和可视化工具,我们先来看看微软官方是怎么介绍的: Po ...

  10. linux专题(九):磁盘管理

    http://dwz.date/UDf 概述 Linux磁盘管理好坏直接关系到整个系统的性能问题. Linux磁盘管理常用命令为 df.du. df :列出文件系统的整体磁盘使用量 du:检查磁盘空间 ...