软件测试软件测试之路颠覆你的Python实践

python3使用pymysql操作mysql

2017-08-04  本文已影响1914人  亭子青年

数据库知识

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

数据库产品介绍

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. 关闭数据库连接

学习笔记

#正常构造语句的情况
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'被转义的语句。
#方式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

上一篇 下一篇

猜你喜欢

热点阅读