1001系列之pandas0001如何从Mysql数据库中导入导出数据

一、Pymysql模块简介

    Mysql数据库是数据挖掘任务的数据源之一,通过pymysql模块可以直接连接MySQL数据库,进行增删改查等操作。
Python连接MySQL的流程如下:

在这里插入图片描述

1.1cursor(游标)的作用

    为什么要建立一个cursor(游标)?
    因为当python与数据库连接时并不是一次性读取了所有数据,而是根据SQL语言进行操作。cursor在这里相当于执行SQL查询的货车,在Mysql数据库和Python程序之间传递信息。

在这里插入图片描述

二、实际操作连接数据库

2.1 导入pymysql

#导入数值运算numpy、数据分析pandas、数据库连接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 连接的最简全部环节

#连接的全流程
#导入pymysql模块
import pymysql

#创建实例化对象
db = pymysql.connect(host="localhost",
                     user="root",
                     password="*********",
                     database="orderinfo",
                     charset='utf8mb4',
                     cursorclass=pymysql.cursors.DictCursor)
#创建游标
cursor = db.cursor()

#编写SQL语句
sql = "select * from ad limit 5000" 

#执行SQL语句
cursor.execute(sql)  

#取回查询结果集,并将字符串类型结果集转换为列表
result =  cursor.fetchall()
finalresult = list(result) 

#关闭游标
cursor.close() 

#关闭数据库连接
db.close() 
以上是从数据库中导入数据到Python内存中,没有修改数据库,如果修改数据库,需要增加一个步骤
#导入pymysql模块
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语句
sql = """CREATE TABLE EMPLOYEE (
         FIRST_NAME  CHAR(20) NOT NULL,
         LAST_NAME  CHAR(20),
         AGE INT,  
         SEX CHAR(1),
         INCOME FLOAT )"""   #SQL语句不区分大小写

#执行SQL语句
cursor.execute(sql) 

#提交执行之后不会直接在Mysql中执行,需要提交数据库执行,类似修改数据库的操作都需要db.commit()
db.commit()

#向新建的表中插入数据
sql = "INSERT INTO EMPLOYEE(FIRST_NAME, \
       LAST_NAME, AGE, SEX, INCOME) \
       VALUES ('%s', '%s',  %s,  '%s',  %s)" % \
       ('Mac','Mohan',20, 'M',2000)
       
# 执行sql语句
cursor.execute(sql)
# 执行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连接防止程序崩溃

#方法一,连接过程使用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"            #SQL查询代码,不需要分号
    t_start = time.time()                          #设置程序运行开始时间戳
    cursor.execute(sql)                            #游标执行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结构连接

#连接方法二,用with结构,既可以防止程序崩溃,也可以在执行SQL语句之后自动关闭游标
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)
       
        # 执行sql语句
        cursor.execute(sql)
        # 执行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() #注意这里只有commit才真正开始执行
    finally:
        cursor.close()
        conn.close()

# if __name__ = "__main__":
#     sql = "SELECT * FROM EMPLOYEE"
#     get_query(sql)

三、案例实操

1.从Excel中读取数据,json行简单整理
2.通过Python将数据导入Mysql数据库存储
3.再从Mysql数据库中导出到Python进行数据分析

3.1 从excel中导入数据

#电商产品详情表
dt1 = pd.read_excel(r"C:\Users\1001LoadData\Product_details_rawdata.xlsx")
#查看表的前5行
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 连接数据库并创建一张新表

#连接数据库,创建数据表Product_details_rawdata对象
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))"""
#成功调用向数据库orderinfo中创建一张新的空表
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;

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

#mysql不能直接导入excel文件,只能导入CSV文件,所以若想导入excel文件,还需要转换,
#转换之后还需要在记事本中重新打开,选择utf_8编码

方法二:通过mysqlworkbench图形界面导入文件

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

方法三:通过for循环一句一句插入到表中

#方法三通过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自带的导入数据库的功能

#方法四通过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

#取出orderinfo库中的Product_details_rawdata表中的全部记录
sql3 = "select * from Product_details_rawdata"        #取出表中所有数据的SQL代码
orginal_data = get_query(sql3)                        #调用函数取出数据
dt2 = pd.DataFrame(orginal_data,columns=col)          #转换为DataFrame
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

猜你喜欢

转载自blog.csdn.net/lqw844597536/article/details/116976657