pandas DataFrame.to_sql()用法小结

 更新时间:2024年02月21日 10:18:12   作者:stone0823  
Pandas是基于NumPy的一种工具,该工具是为了解决数据分析任务而创建的,本文主要介绍了pandas DataFrame.to_sql()用法小结,感兴趣的可以了解一下

to_sql() 的语法如下:

# https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_sql.html

DataFrame.to_sql(name, con, schema=None, 
if_exists='fail', index=True, index_label=None, 
chunksize=None, dtype=None, method=None)

我们从一个简单的例子开始。在 mysql 数据库中有一个 emp_data 表,假设我们使用 pandas DataFrame ,将数据拷贝到另外一个新表 emp_backup

import pandas as pd
from sqlalchemy import create_engine
import sqlalchemy

engine = create_engine('mysql+pymysql://user:password@localhost/stonetest?charset=utf8')
df = pd.read_sql('emp_master', engine)
df.to_sql('emp_backup', engine)

使用 mysql 的 describe 命令比较 emp_master 表和 emp_backup 表结构:

mysql> describe emp_master;
+----------------+-------------+------+-----+---------+-------+
| Field          | Type        | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+-------+
| EMP_ID         | int(11)     | NO   | PRI | NULL    |       |
| GENDER         | varchar(10) | YES  |     | NULL    |       |
| AGE            | int(11)     | YES  |     | NULL    |       |
| EMAIL          | varchar(50) | YES  |     | NULL    |       |
| PHONE_NR       | varchar(20) | YES  |     | NULL    |       |
| EDUCATION      | varchar(20) | YES  |     | NULL    |       |
| MARITAL_STAT   | varchar(20) | YES  |     | NULL    |       |
| NR_OF_CHILDREN | int(11)     | YES  |     | NULL    |       |
+----------------+-------------+------+-----+---------+-------+
8 rows in set (0.00 sec)

emp_backup 表结构:

mysql> describe emp_backup;
+----------------+------------+------+-----+---------+-------+
| Field          | Type       | Null | Key | Default | Extra |
+----------------+------------+------+-----+---------+-------+
| index          | bigint(20) | YES  | MUL | NULL    |       |
| EMP_ID         | bigint(20) | YES  |     | NULL    |       |
| GENDER         | text       | YES  |     | NULL    |       |
| AGE            | bigint(20) | YES  |     | NULL    |       |
| EMAIL          | text       | YES  |     | NULL    |       |
| PHONE_NR       | text       | YES  |     | NULL    |       |
| EDUCATION      | text       | YES  |     | NULL    |       |
| MARITAL_STAT   | text       | YES  |     | NULL    |       |
| NR_OF_CHILDREN | bigint(20) | YES  |     | NULL    |       |
+----------------+------------+------+-----+---------+-------+
9 rows in set (0.00 sec)

我们发现,to_sql() 并没有考虑将 emp_master 表字段的数据类型同步到目标表,而是简单的区分数字型和字符型,这是第一个问题,第二个问题呢,目标表没有 primary key。因为 pandas 定位是数据分析工具,数据源可以来自 CSV 这种文本型文件,本身是没有严格数据类型的。而且,pandas 数据 to_excel() 或者to_sql() 只是方便数据存放到不同的目的地,本身也不是一个数据库升迁工具。

但如果我们需要严格保留原表字段的数据类型,以及同步 primary key,该怎么做呢?

使用 SQL 语句来创建表结构

如果数据源本身是来自数据库,通过脚本操作是比较方便的。如果数据源是来自 CSV 之类的文本文件,可以手写 SQL 语句或者利用 pandas get_schema() 方法,如下例:

import sqlalchemy

print(pd.io.sql.get_schema(df, 'emp_backup', keys='EMP_ID', 
   dtype={'EMP_ID': sqlalchemy.types.BigInteger(),
       'GENDER': sqlalchemy.types.String(length=20),
       'AGE': sqlalchemy.types.BigInteger(),
       'EMAIL':  sqlalchemy.types.String(length=50),
       'PHONE_NR':  sqlalchemy.types.String(length=50),
       'EDUCATION':  sqlalchemy.types.String(length=50),
       'MARITAL_STAT':  sqlalchemy.types.String(length=50),
       'NR_OF_CHILDREN': sqlalchemy.types.BigInteger()
       }, con=engine))

get_schema()并不是一个公开的方法,没有文档可以查看。生成的 SQL 语句如下:

CREATE TABLE emp_backup (
        `EMP_ID` BIGINT NOT NULL AUTO_INCREMENT,
        `GENDER` VARCHAR(20),
        `AGE` BIGINT,
        `EMAIL` VARCHAR(50),
        `PHONE_NR` VARCHAR(50),
        `EDUCATION` VARCHAR(50),
        `MARITAL_STAT` VARCHAR(50),
        `NR_OF_CHILDREN` BIGINT,
        CONSTRAINT emp_pk PRIMARY KEY (`EMP_ID`)
)

to_sql() 方法使用 append 方式插入数据

to_sql() 方法的 if_exists 参数用于当目标表已经存在时的处理方式,默认是 fail,即目标表存在就失败,另外两个选项是 replace 表示替代原表,即删除再创建,append 选项仅添加数据。使用 append 可以达到目的。

import pandas as pd
from sqlalchemy import create_engine
import sqlalchemy

engine = create_engine('mysql+pymysql://user:password@localhost/stonetest?charset=utf8')
df = pd.read_sql('emp_master', engine)
# make sure emp_master_backup table has been created
# so the table schema is what we want
df.to_sql('emp_backup', engine, index=False, if_exists='append')

也可以在 to_sql() 方法中,通过 dtype 参数指定字段的类型,然后在 mysql 中 通过 alter table 命令将字段 EMP_ID 变成 primary key。

df.to_sql('emp_backup', engine, if_exists='replace', index=False,
          dtype={'EMP_ID': sqlalchemy.types.BigInteger(),
                 'GENDER': sqlalchemy.types.String(length=20),
                 'AGE': sqlalchemy.types.BigInteger(),
                 'EMAIL':  sqlalchemy.types.String(length=50),
                 'PHONE_NR':  sqlalchemy.types.String(length=50),
                 'EDUCATION':  sqlalchemy.types.String(length=50),
                 'MARITAL_STAT':  sqlalchemy.types.String(length=50),
                 'NR_OF_CHILDREN': sqlalchemy.types.BigInteger()
                 })

with engine.connect() as con:
    con.execute('ALTER TABLE emp_backup ADD PRIMARY KEY (`EMP_ID`);')

当然,如果数据源本身就是 mysql,当然不用大费周章来创建数据表的结构,直接使用 create table like xxx 就行。以下代码展示了这种用法:

import pandas as pd 
from sqlalchemy import create_engine

engine = create_engine('mysql+pymysql://user:password@localhost/stonetest?charset=utf8')
df = pd.read_sql('emp_master', engine)

# Copy table structure
with engine.connect() as con:
    con.execute('DROP TABLE if exists emp_backup')
    con.execute('CREATE TABLE emp_backup LIKE emp_master;')

df.to_sql('emp_backup', engine, index=False, if_exists='append')

 到此这篇关于pandas DataFrame.to_sql()用法小结的文章就介绍到这了,更多相关pandas DataFrame.to_sql() 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python数据分析之pandas比较操作

    Python数据分析之pandas比较操作

    比较操作是很简单的基础知识,不过Pandas中的比较操作有一些特殊的点,本文介绍的非常详细,对正在学习python的小伙伴们很有帮助.需要的朋友可以参考下
    2021-05-05
  • python自定义模块使用.pth文件实现重用方式

    python自定义模块使用.pth文件实现重用方式

    这篇文章主要介绍了python自定义模块使用.pth文件实现重用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-02-02
  • 详解Python中string模块除去Str还剩下什么

    详解Python中string模块除去Str还剩下什么

    这篇文章主要介绍了详解Python中string模块除去Str还剩下什么,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • 用Python实现换行符转换的脚本的教程

    用Python实现换行符转换的脚本的教程

    这篇文章主要介绍了用Python实现换行符转换的脚本的教程,代码非常简单,包括一个对操作说明的功能的实现,需要的朋友可以参考下
    2015-04-04
  • Python反爬实战掌握酷狗音乐排行榜加密规则

    Python反爬实战掌握酷狗音乐排行榜加密规则

    最新的酷狗音乐反爬来袭,本文介绍如何利用Python掌握酷狗排行榜加密规则,本章内容只限学习,切勿用作其他用途!!!!! 有需要的朋友可以借鉴参考下
    2021-10-10
  • Python matplotlib绘制图形实例(包括点,曲线,注释和箭头)

    Python matplotlib绘制图形实例(包括点,曲线,注释和箭头)

    这篇文章主要介绍了Python matplotlib绘制图形实例(包括点,曲线,注释和箭头),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-04-04
  • python 写的一个爬虫程序源码

    python 写的一个爬虫程序源码

    这篇文章主要介绍了python 写的一个爬虫程序源码,需要的朋友可以参考下
    2016-02-02
  • Python实现socket库网络通信套接字

    Python实现socket库网络通信套接字

    socket又叫套接字,实现网络通信的两端就是套接字。分为服务器对应的套接字和客户端对应的套接字,本文给大家介绍Python实现socket库网络通信套接字的相关知识,包括套接字的基本概念,感兴趣的朋友跟随小编一起看看吧
    2021-06-06
  • 苹果Macbook Pro13 M1芯片安装Pillow的方法步骤

    苹果Macbook Pro13 M1芯片安装Pillow的方法步骤

    Pillow作为python的第三方图像处理库,提供了广泛的文件格式支持,本文主要介绍了苹果Macbook Pro13 M1芯片安装Pillow,具有一定的参考价值,感兴趣的可以了解一下
    2021-11-11
  • pygame加载中文名mp3文件出现error

    pygame加载中文名mp3文件出现error

    本文主要介绍了pygame加载中文名mp3文件出现error的解决方案。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-03-03

最新评论