一、Pymysql模块简介
Mysql数据库是数据挖掘任务的数据源之一,通过pymysql模块可以直接连接MySQL数据库,进行增删改查等操作。
Python连接MySQL的流程如下:
1.1cursor(游标)的作用
为什么要建立一个cursor(游标)?
因为当python与数据库连接时并不是一次性读取了所有数据,而是根据SQL语言进行操作。cursor在这里相当于执行SQL查询的货车,在Mysql数据库和Python程序之间传递信息。
二、实际操作连接数据库
2.1 导入pymysql
import pandas as pd
import numpy as np
import pymysql
import time
2.2 连接Mysql数据库
db = pymysql. connect( host= "localhost" ,
user= "root" ,
password= "********" ,
database= "orderinfo" ,
charset= 'utf8mb4' ,
cursorclass= pymysql. cursors. DictCursor)
2.2.1 pymysql.connect()参数说明
host( str ) : MySQL服务器地址,默认为本地主机( localhost)
port( int ) : MySQL服务器端口号,默认为当前用户
user( str ) : 用户名,没有默认值
password( str ) : 连接密码,没有默认值
db( str ) : 数据库名称
charset( str ) : 连接编码
cursorclass( str ) : cursor( ) 使用的种类,默认值为MySQLdb. cursors. Cursor
2.2.2pymysql.connect()实例对象方法说明
db. close( ) : 可关闭数据库连接,并释放相关资源。
db. cursor( [ cursorClass] ) : 返回一个指针对象,用于访问和操作数据库中的数据。
db. begin( ) : 用于开始一个事务,如果数据库的AUTOCOMMIT已经开启就关闭它,直到事务调用commit( ) 和rollback( ) 结束。
db. commit( ) : 表示事务提交
db. rollback( ) : 表示事务回退
2.3 创建游标
cursor = db. cursor( )
2.3.1 db.cursor()指针对象游标的方法
cursor( ) 的类型, 括号在中不填默认为元组,还有DictCursor: 字典类型,SSCursor: 无缓冲元组类型,SSDictCursor: 无缓冲字典类型
无缓冲游标类型,适用于数据量很大,一次性返回太慢,或者服务端带宽较小;创建连接时,通过cursorclass 参数指定类型。
cursor. close( ) : 方法,关闭指针并释放相关资源。
cursor. execute( query[ , parameters] ) : 执行数据库查询。
cursor. fetchall( ) : 方法,可取出指针结果集中的所有行,返回的结果集一个元组( tuples) 。
cursor. fetchmany( [ size= cursor. arraysize] ) : 方法,从查询结果集中取出多行,我们可利用可选的参数指定取出的行数。
cursor. fetchone( ) : 方法,从查询结果集中返回下一行。
cursor. arraysize: 属性, 指定由cursor. fetchmany( ) 方法返回行的数目,影响fetchall( ) 的性能,默认值为1 。
cursor. rowcount: 属性, 指出上次查询或更新所发生行数。- 1 表示还没开始查询或没有查询到数据。
2.4 连接的最简全部环节
import pymysql
db = pymysql. connect( host= "localhost" ,
user= "root" ,
password= "*********" ,
database= "orderinfo" ,
charset= 'utf8mb4' ,
cursorclass= pymysql. cursors. DictCursor)
cursor = db. cursor( )
sql = "select * from ad limit 5000"
cursor. execute( sql)
result = cursor. fetchall( )
finalresult = list ( result)
cursor. close( )
db. close( )
以上是从数据库中导入数据到Python内存中,没有修改数据库,如果修改数据库,需要增加一个步骤
import pymysql
db = pymysql. connect( host= "localhost" ,
user= "root" ,
password= "**********" ,
database= "orderinfo" ,
charset= 'utf8mb4' ,
cursorclass= pymysql. cursors. DictCursor)
cursor = db. cursor( )
cursor. execute( "drop table if exists employee" )
sql = """CREATE TABLE EMPLOYEE (
FIRST_NAME CHAR(20) NOT NULL,
LAST_NAME CHAR(20),
AGE INT,
SEX CHAR(1),
INCOME FLOAT )"""
cursor. execute( sql)
db. commit( )
sql = "INSERT INTO EMPLOYEE( FIRST_NAME, \
LAST_NAME, AGE, SEX, INCOME) \
VALUES ( '%s' , '%s' , % s, '%s' , % s) " % \
( 'Mac' , 'Mohan' , 20 , 'M' , 2000 )
cursor. execute( sql)
db. commit( )
cursor. close( )
db. close( )
D:\Anaconda3\lib\site-packages\pymysql\cursors.py:329: Warning: (1051, "Unknown table 'tencent_ad.employee'")
self._do_get_result()
但是这样连接,过程中可能会出现程序异常情况,为了防止程序崩溃,采用以下两种方法增强代码鲁棒性。
2.4.1 方法一:使用try…except连接防止程序崩溃
import pymysql
db = pymysql. connect( host= "localhost" ,
user= "root" ,
password= "**********" ,
database= "orderinfo" ,
charset= 'utf8mb4' ,
cursorclass= pymysql. cursors. DictCursor)
cursor = db. cursor( )
try :
sql = "select * from ad limit 5000"
t_start = time. time( )
cursor. execute( sql)
result = cursor. fetchall( )
finalresult = list ( result)
t_mid = time. time( )
print ( "成功获取数据!总共用时:" , t_mid- t_start)
except Exception as e:
cursor. rollback
finally :
cursor. close( )
db. close( )
t_end = time. time( )
print ( "连接完毕!总共用时:" , t_end- t_start)
成功获取数据!总共用时: 0.06984472274780273
连接完毕!总共用时: 0.06984472274780273
2.4.2 方法二:用with as结构连接
import pymysql
db = pymysql. connect( host= "localhost" ,
user= "root" ,
password= "***********" ,
database= "orderinfo" ,
charset= 'utf8mb4' ,
cursorclass= pymysql. cursors. DictCursor)
cursor = db. cursor( )
try :
with db. cursor( ) as cursor:
cursor. execute( "drop table if exists employee" )
sql = """CREATE TABLE EMPLOYEE (
FIRST_NAME CHAR(20) NOT NULL,
LAST_NAME CHAR(20),
AGE INT,
SEX CHAR(1),
INCOME FLOAT )"""
cursor. execute( sql)
db. commit( )
with db. cursor( ) as cursor:
sql = "INSERT INTO EMPLOYEE( FIRST_NAME, \
LAST_NAME, AGE, SEX, INCOME) \
VALUES ( '%s' , '%s' , % s, '%s' , % s) " % \
( 'Mac' , 'Mohan' , 20 , 'M' , 2000 )
cursor. execute( sql)
db. commit( )
with db. cursor( ) as cursor:
sql = "SELECT * FROM EMPLOYEE"
cursor. execute( sql)
result = cursor. fetchone( )
print ( result)
finally :
db. close( )
{'FIRST_NAME': 'Mac', 'LAST_NAME': 'Mohan', 'AGE': 20, 'SEX': 'M', 'INCOME': 2000.0}
2.4.3 封装函数以提高代码复用
def get_con ( ) :
"""
获取MySql连接,return:mysql connection
"""
return pymysql. connect( host= "localhost" ,
user= "root" ,
password= "**********" ,
database= "orderinfo" ,
charset= 'utf8mb4' ,
cursorclass= pymysql. cursors. DictCursor)
def get_query ( sql) :
"""
根据SQL代码进行查询,并返回结果
paramater SQL
return str"""
conn = get_con( )
try :
cursor = conn. cursor( )
cursor. execute( sql)
conn. commit( )
return list ( cursor. fetchall( ) )
finally :
cursor. close( )
conn. close( )
def insert_or_update ( sql) :
"""
执行插入或更新数据操作
paramater insert SQL or update SQL
return None"""
conn = get_con( )
try :
cursor = conn. cursor( )
cursor. execute( sql)
conn. commit( )
finally :
cursor. close( )
conn. close( )
三、案例实操
1.从Excel中读取数据,json行简单整理
2.通过Python将数据导入Mysql数据库存储
3.再从Mysql数据库中导出到Python进行数据分析
3.1 从excel中导入数据
dt1 = pd. read_excel( r"C:\Users\1001LoadData\Product_details_rawdata.xlsx" )
dt1. head( 5 )
item_id
item_name
TradeName
price
total_sale
month_sale
accum_comm
TM_points
CollectCount
Tastes
BodyType
ApplicablePhase
Brand
Classification
Breed
Manufacturer
Weight
Origin
ManufacturerAddress
RecipeTastePrescription
0
19045209534
Royal Canin皇家狗粮 德牧幼犬粮AGS30 12KG 大型犬狗粮28省包邮
德国牧羊犬幼犬专用粮 12kg
650.0
2046
39
418
325
348
其他
通用型
幼犬
ROYAL CANIN/皇家
专用粮
德国牧羊犬
皇誉宠物食品(上海)有限公司
12000
中国
上海
NaN
1
547144906363
Royal Canin皇家狗粮 柴犬幼犬专用粮SIJ29/3KG 犬主粮狗粮
日本柴犬幼犬 3000g
285.0
560
39
132
142
200
其他
NaN
幼犬
ROYAL CANIN/皇家
NaN
日本柴犬
皇誉宠物食品(上海)有限公司
3000
中国
上海
NaN
2
26255560615
皇家狗粮 大型犬奶糕MAS30 4KG哺乳孕期犬离乳期幼犬牧羊阿拉斯加
(大型犬)离乳期奶糕 4kg
301.0
1571
27
390
150
554
其他
大型犬
离乳期
ROYAL CANIN/皇家
奶糕
通用型
皇誉宠物食品(上海)有限公司
4000
中国
上海
NaN
3
39792870853
Royal Canin皇家狗粮 迷你雪纳瑞成犬粮SNZ25/3KG 犬主粮
雪纳瑞成犬 3000g
260.0
2113
32
281
130
379
其他
NaN
成犬
ROYAL CANIN/皇家
NaN
雪纳瑞
皇誉宠物食品(上海)有限公司
3000
中国
上海奉贤区肖南路475号
NaN
4
547165690913
Royal Canin皇家狗粮 拉布拉多幼犬粮ALR33 3KG 大型犬全犬种热卖
拉布拉多幼犬 3000g
210.0
643
48
173
105
318
其他
NaN
幼犬
ROYAL CANIN/皇家
NaN
拉布拉多
皇誉宠物食品(上海)有限公司
3000
中国
上海
NaN
dt1. info( memory_usage= "deep" )
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 183 entries, 0 to 182
Data columns (total 20 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 item_id 183 non-null int64
1 item_name 183 non-null object
2 TradeName 183 non-null object
3 price 183 non-null float64
4 total_sale 183 non-null int64
5 month_sale 183 non-null int64
6 accum_comm 183 non-null int64
7 TM_points 183 non-null int64
8 CollectCount 183 non-null int64
9 Tastes 183 non-null object
10 BodyType 137 non-null object
11 ApplicablePhase 183 non-null object
12 Brand 183 non-null object
13 Classification 148 non-null object
14 Breed 156 non-null object
15 Manufacturer 183 non-null object
16 Weight 183 non-null int64
17 Origin 183 non-null object
18 ManufacturerAddress 183 non-null object
19 RecipeTastePrescription 79 non-null object
dtypes: float64(1), int64(7), object(12)
memory usage: 212.6 KB
col = dt1. columns
col
Index(['item_id', 'item_name', 'TradeName', 'price', 'total_sale',
'month_sale', 'accum_comm', 'TM_points', 'CollectCount', 'Tastes',
'BodyType', 'ApplicablePhase', 'Brand', 'Classification', 'Breed',
'Manufacturer', 'Weight', 'Origin', 'ManufacturerAddress',
'RecipeTastePrescription'],
dtype='object')
varchar = "varchar(60)"
int_ = "int"
float_ = "float"
datatype = [ int_, varchar, varchar, float_, int_, int_, int_, int_, int_, varchar, varchar, varchar, varchar, varchar, varchar, varchar, int_, varchar, varchar, varchar]
ncol = pd. DataFrame( list ( zip ( col, datatype) ) )
ncol[ "new" ] = ncol[ 0 ] + " " + ncol[ 1 ] + ","
print ( ncol[ "new" ] )
0 item_id int,
1 item_name varchar(60),
2 TradeName varchar(60),
3 price float,
4 total_sale int,
5 month_sale int,
6 accum_comm int,
7 TM_points int,
8 CollectCount int,
9 Tastes varchar(60),
10 BodyType varchar(60),
11 ApplicablePhase varchar(60),
12 Brand varchar(60),
13 Classification varchar(60),
14 Breed varchar(60),
15 Manufacturer varchar(60),
16 Weight int,
17 Origin varchar(60),
18 ManufacturerAddress varchar(60),
19 RecipeTastePrescription varchar(60),
Name: new, dtype: object
3.2 连接数据库并创建一张新表
sql1 = """create table Product_details_rawdata(
item_id bigint,
item_name varchar(120),
TradeName varchar(60),
price float,
total_sale int,
month_sale int,
accum_comm int,
TM_points int,
CollectCount int,
Tastes varchar(60),
BodyType varchar(60),
ApplicablePhase varchar(60),
Brand varchar(60),
Classification varchar(60),
Breed varchar(60),
Manufacturer varchar(60),
Weight int,
Origin varchar(60),
ManufacturerAddress varchar(60),
RecipeTastePrescription varchar(60))"""
insert_or_update( sql1)
3.3 将数据导入数据库
方法一:通过命令行进行文件导入
有时候想要一次性导入文件怎么办呢?
在MySQL 8.0中导入csv文件的步骤(因为有安全保护模式,不能在可视化工具或者命令行中直接导入文件):
1.已管理员身份启动windows命令行。
2.使用 mysql --local-infile=1 -u root -p 命令连接数据库。
3.接触安全模式 set global local_infile = 'ON';
4.查看数据库,使用数据库,查看表 show databases;use orderinfo;desc orderdata;
5.使用下面的命令导入csv文件,注意文件比较大的话,导入时间比较长,光标会在下一行闪动,请耐心等待。
->load data local infile "E:\\CBdata\\1、orderdata\\output.csv"
->into table orderdata
->fields terminated by ","
->ignore 1 lines;
方法二:通过mysqlworkbench图形界面导入文件
方法三:通过for循环一句一句插入到表中
for i in range ( 10 ) :
sql2 = "INSERT INTO Product_details_rawdata( item_id, item_name, TradeName, price, total_sale, \
month_sale, accum_comm, TM_points, CollectCount, Tastes, \
BodyType, ApplicablePhase, Brand, Classification, Breed, \
Manufacturer, Weight, Origin, ManufacturerAddress, \
RecipeTastePrescription) VALUES ( % s, '%s' , '%s' , % s, % s, % s, % s, % s, % s, '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , % s, '%s' , '%s' , '%s' ) " % \
tuple ( dt1. iloc[ i, : ] . values)
insert_or_update( sql2)
方法四:通过pandas自带的导入数据库的功能
from sqlalchemy import create_engine
engine = create_engine( 'mysql+pymysql://root:password@localhost:3306/orderinfo' )
dt1. to_sql( name= 'Product_details_rawdata' , con= engine, chunksize= 1000 , if_exists= 'append' , index= None )
D:\Anaconda3\lib\site-packages\pymysql\cursors.py:170: Warning: (1366, "Incorrect string value: '\\xD6\\xD0\\xB9\\xFA\\xB1\\xEA...' for column 'VARIABLE_VALUE' at row 533")
result = self._query(query)
D:\Anaconda3\lib\site-packages\pandas\io\sql.py:1422: UserWarning: The provided table name 'Product_details_rawdata' is not found exactly as such in the database after writing the table, possibly due to case sensitivity issues. Consider using lower case table names.
warnings.warn(msg, UserWarning)
3.4 将数据从数据库查询导出到pandas
sql3 = "select * from Product_details_rawdata"
orginal_data = get_query( sql3)
dt2 = pd. DataFrame( orginal_data, columns= col)
dt2
item_id
item_name
TradeName
price
total_sale
month_sale
accum_comm
TM_points
CollectCount
Tastes
BodyType
ApplicablePhase
Brand
Classification
Breed
Manufacturer
Weight
Origin
ManufacturerAddress
RecipeTastePrescription
0
19045209534
Royal Canin皇家狗粮 德牧幼犬粮AGS30 12KG 大型犬狗粮28省包邮
德国牧羊犬幼犬专用粮 12kg
650.0
2046
39
418
325
348
其他
通用型
幼犬
ROYAL CANIN/皇家
专用粮
德国牧羊犬
皇誉宠物食品(上海)有限公司
12000
中国
上海
None
1
547144906363
Royal Canin皇家狗粮 柴犬幼犬专用粮SIJ29/3KG 犬主粮狗粮
日本柴犬幼犬 3000g
285.0
560
39
132
142
200
其他
None
幼犬
ROYAL CANIN/皇家
None
日本柴犬
皇誉宠物食品(上海)有限公司
3000
中国
上海
None
2
26255560615
皇家狗粮 大型犬奶糕MAS30 4KG哺乳孕期犬离乳期幼犬牧羊阿拉斯加
(大型犬)离乳期奶糕 4kg
301.0
1571
27
390
150
554
其他
大型犬
离乳期
ROYAL CANIN/皇家
奶糕
通用型
皇誉宠物食品(上海)有限公司
4000
中国
上海
None
3
39792870853
Royal Canin皇家狗粮 迷你雪纳瑞成犬粮SNZ25/3KG 犬主粮
雪纳瑞成犬 3000g
260.0
2113
32
281
130
379
其他
None
成犬
ROYAL CANIN/皇家
None
雪纳瑞
皇誉宠物食品(上海)有限公司
3000
中国
上海奉贤区肖南路475号
None
4
547165690913
Royal Canin皇家狗粮 拉布拉多幼犬粮ALR33 3KG 大型犬全犬种热卖
拉布拉多幼犬 3000g
210.0
643
48
173
105
318
其他
None
幼犬
ROYAL CANIN/皇家
None
拉布拉多
皇誉宠物食品(上海)有限公司
3000
中国
上海
None
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
178
521103456733
海洋之星深海鱼成犬狗粮无谷天然粮中小型犬成犬狗粮12kg小颗粒
成犬无谷物深海鱼大颗粒配方犬粮 其它
710.0
7173
388
2226
355
1171
鱼肉味
通用型
成犬
Fish4Dogs/海洋之星
犬粮
通用型
山东海创工贸有限公司
6000
中国
山东省聊城市经济开发区牡丹江路8号
无谷物深海鱼大颗粒配方
179
545052402563
海洋之星狗粮试吃装泰迪比熊玩具犬幼犬成犬全犬期小颗粒三包*30g
全犬期鱼味犬粮 100g
9.9
10623
349
3003
12
578
鱼肉味
None
全犬期
Fish4Dogs/海洋之星
犬粮
通用型
海洋之星
100
其他
Fish4Dogs.Ltd
鱼味
180
521103920550
海洋之星狗粮通用型天然粮中小型犬幼犬主粮泰迪博美比熊1.5kg
幼犬无谷物深海鱼幼犬配方大颗粒犬粮 1.5kg
160.0
25402
614
7582
80
7682
鱼肉味
通用型
幼犬
Fish4Dogs/海洋之星
犬粮
通用型
山东海创工贸有限公司
1500
中国
山东省聊城市经济开发区牡丹江路8号
无谷物深海鱼幼犬配方大颗粒
181
534102297282
海洋之星狗粮试吃装泰迪比熊贵宾幼犬通用型小颗粒美毛三包*30g
(中小型犬)幼犬深海鱼配方犬粮 100g
9.9
30387
1018
8754
4
2003
鱼肉味
中小型犬
幼犬
Fish4Dogs/海洋之星
犬粮
通用型
海洋之星
100
其他
Fish4Dogs.Ltd
深海鱼配方
182
521100097514
海洋之星三文鱼狗粮泰迪吉娃娃贵宾玩具犬狗粮无谷天然粮6kg
贵宾/泰迪无谷物三文鱼玩具犬配方犬粮
440.0
8286
573
2659
220
1750
鱼肉味
小型犬
全犬期
Fish4Dogs/海洋之星
专用粮
贵宾/泰迪
山东海创工贸有限公司
6000
中国
山东省聊城市经济开发区牡丹江路8号
无谷物三文鱼玩具犬配方
183 rows × 20 columns