python3使用pymysql操作mysql

作者: 亭子青年 | 来源:发表于2017-08-04 18:12 被阅读1914次

数据库知识

数据库种类概述之数据库分类

  • SQL NoSQL(非关系型数据库,弥补关系型数据库的缺点,可以存储json对象)
  • 单机(数据库运行在一台服务器上) 分布式(数据库运行在服务器集群上)
  • 文件型(数据存放在硬盘) 内存型(数据存放在内存里)
  • 批处理 交互式(分级查询之后汇总)----分布式数据库的子

数据库产品介绍

SQL:mysql(开源,免费),postgre sql(开源,免费),SQLserver,oricle
NoSQL:mongoDB(使用最广泛的一种数据库),neo4j(性能有问题),elasticsearch(全文检索),influxDB(性能有问题)
单机:mysql,postgre sql
分布式:hive,impala
文件型数据库:mysql,mongDB
内存型数据库:redis(支持复杂的数据类型),memcached

amazon web services==>AWS==>亚马逊云平台提供商===》注册可以免费使用一年的套餐,可以免费提供mysql,PostgreSQL的服务。

mysql

mysql数据库属于中小型数据库,对于中小型企业比较合适。

python 操作mysql

MySQL Python客户端包括3个,官方提供的mysql-connector(自带的这个游标不能被封装到函数中,会报错,比较不适用),第三方客户端MySQLdb(python2使用MySQLdb,python3使用pymysql),MySQldb的二次封装torndb

由于本机安装的是python3,所以这里采用第二种方式:pymysql客户端来进行学习


学习笔记

api操作流程流程

  1. 引入API模块
  2. 获取与数据库的连接
  3. 执行SQL语句和存储过程
  4. 关闭数据库连接

学习笔记

  • pymysql安装:pip install pymysql
  • pymysql中所有的有关更新数据(insertupdatedelete)的操作都需要commit,否则无法将数据提交到数据库,既然有了commit(),就一定有对应的rollback(),commit()表示提交,rollback()表示回滚
  • 调用无参数存储过程:可以使用cursor.callproc('p2') #等价于cursor.execute("call p2()")
  • 调用有参数的存储过程:cursor.callproc('p1', args=(1, 22, 3, 4))
  • 关于pymysql防注入,字符串拼接查询,容易造成注入,为了避免注入,使用pymysql提供的参数化语句
#正常构造语句的情况
sql="select user,pass from tb7 where user='%s' and pass='%s'" % (user,passwd)
row_count=cursor.execute(sql)
#拼接语句被构造成下面这样,永真条件,此时就注入成功了。因此要避免这种情况需使用pymysql提供的参数化查询。
#select user,pass from tb7 where user='u1' or '1'-- ' and pass='u1pass'

execute执行sql语句的时候,必须使用参数化的方式,否则必然产生SQL注入漏洞

#避免注入,使用pymysql提供的参数化语句
user="u1' or '1'-- "
passwd="u1pass"
#执行参数化查询
row_count=cursor.execute("select user,pass from tb7 where user=%s and pass=%s",(user,passwd))
#内部执行参数化生成的SQL语句,对特殊字符进行了加\转义,避免注入语句生成。
# sql=cursor.mogrify("select user,pass from tb7 where user=%s and pass=%s",(user,passwd))
# print sql
#select user,pass from tb7 where user='u1\' or \'1\'-- ' and pass='u1pass'被转义的语句。
  • 使用mysql存储过程动态执行SQL防注入,使用cursor.callproc('p2',(1,2,3,4))
  • sql语句中存在中文字符的时候,需要在pymysql.connect()的时候,指定添加参数charset='utf8',否则中文显示为乱码。
  • 获取查询数据:cursor.fetchone()获取剩余结果的第一行数据,cursor.fetchmany(3)获取剩余结果的前3行数据,cursor.fetchall()获取剩余结果的所有数据。
  • cursor提供一个参数可以获取最新insert自增的id,也就是最后插入的一条数据ID,如果没有insert过,执行cursor.lastrowid会报错
  • 游标是可以移动的,通过cursor.scroll()来移动
  • 关于pymysql默认select获取的数据是元祖类型,如果想要字典类型的数据,有两种方式
#方式1:pymysql.connection()中指定参数
conn = pymysql.connect(
    host = "127.0.0.1",
    user = "root",
    password = "",
    database = "hetingdemo",
    charset = 'utf8',
    cursorclass = pymysql.cursors.DictCursor)

#方式2:conn.cursor()中指定参数
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)

实例

实例1:创建数据库(创建表)

#!/usr/bin/env python
#coding=utf-8

import pymysql

#创建数据库连接,注意这里我加入了charset和cursorclass参数
conn = pymysql.connect(
    host = "127.0.0.1",
    user = "root",
    password = "",
    database = "hetingdemo",
    charset = 'utf8',
    cursorclass = pymysql.cursors.DictCursor)

#获取游标
cursor = conn.cursor()
#构建数据表的sql语句
sql = '''
CREATE TABLE para5(
    id int UNSIGNED AUTO_INCREMENT  ,
    name varchar(30) NOT NULL,
    age int NOT NULL,
    PRIMARY KEY(id)
)ENGINE=INNODB DEFAULT charset=utf8;
'''

try:
    # 执行sql语句
    cursor.execute(sql)
    # 提交执行
    conn.commit()
except Exception as  e:
    # 如果执行sql语句出现问题,则执行回滚操作
    conn.rollback()
    print(e)
finally:
    # 不论try中的代码是否抛出异常,这里都会执行
    # 关闭游标和数据库连接
    cursor.close()
    conn.close()

实例2:insert数据

#!/usr/bin/env python
#coding=utf-8

import pymysql

#创建数据库连接,注意这里我加入了charset和cursorclass参数
conn = pymysql.connect(
    host = "127.0.0.1",
    user = "root",
    password = "",
    database = "hetingdemo",
    charset = 'utf8',
    cursorclass = pymysql.cursors.DictCursor)
#获取游标
cursor = conn.cursor()

try:
    # 执行一条insert语句,返回受影响的行数
    # cursor.execute("INSERT INTO para5(name,age) VALUES(%s,%s);",('次牛','12'))
    # 执行多次insert并返回受影响的行数
    cursor.executemany("INSERT INTO para5(name,age) VALUES(%s,%s);", [('次牛444', '12'), ("次牛2", '11'), ('次牛3', '10')])
    # 提交执行
    conn.commit()
except Exception as e:
    # 如果执行sql语句出现问题,则执行回滚操作
    conn.rollback()
    print(e)
finally:
    # 不论try中的代码是否抛出异常,这里都会执行
    # 关闭游标和数据库连接
    cursor.close()
    conn.close()

实例:数据库查询操作

#!/usr/bin/env python
#coding=utf-8

import pymysql

#创建数据库连接,注意这里我加入了charset和cursorclass参数
conn = pymysql.connect(
    host = "127.0.0.1",
    user = "root",
    password = "",
    database = "hetingdemo",
    charset = 'utf8',
    cursorclass = pymysql.cursors.DictCursor)
#获取游标
cursor = conn.cursor()
cursor.execute("SELECT * FROM para5 ;")
#fetchall:获取所有的数据,默认以元祖的方式返回,如果你指定了cursorclass = pymysql.cursors.DictCursor,则以dict的方式返回
#result = cursor.fetchall()
#for row in result:
#    print("id是%d,name是%s,age是%d"%(row["id"],row["name"],row["age"]))
#fetchone:获取剩余数据的第一条数据
result = cursor.fetchone()
print(result)
#fetchmany:获取剩余数据的前2条数据
#result = cursor.fetchmany(2)
#print(result)
cursor.close()
conn.close()

补充

《《补充1》》:pymysql中有几个方法的参数构造上很容易和字符串格式化相互混淆

self.cur.execute(query,params)
self.cur.executemany(query,params)

构造:
cursor.execute("INSERT INTO para5(name,age) VALUES(%s,%s);",('次牛','12'))
cursor.executemany("INSERT INTO para5(name,age) VALUES(%s,%s);", [('次牛444', '12'), ("次牛2", '11'), ('次牛3', '10')])

注意:这里没有字符串格式化里面的%d,%f,只有%s

相关文章

网友评论

  • 干煸屌丝儿:为啥我和你们写的一样,,我的就是1044权限问题
  • 你家旭哥:有没有好的封装方法啊 每个操作都要写try很烦
  • 只想躺赢:def op_sql(self, param):
    try:
    self.cur.execute(param) #执行sql语句
    self.conn.commit()
    return True 是两个param都替换成sql语句吗?还是应该把sql语句放在哪里
    亭子青年:@静默的夜 :smile::smile:
    只想躺赢::disappointed_relieved::disappointed_relieved:重点是sql语句我不知道在那写
    亭子青年:@静默的夜 你调用这个方法的时候,会传递一个sql语句给param参数,这个时候param就被赋值了。 方法里面的这个param就是已经赋值的那个param,直接调用变量使用就可以了

本文标题:python3使用pymysql操作mysql

本文链接:https://www.haomeiwen.com/subject/zvrblxtx.html