pandas DataFrame.to_sql()用法小結(jié)
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 數(shù)據(jù)庫中有一個 emp_data 表,假設我們使用 pandas DataFrame ,將數(shù)據(jù)拷貝到另外一個新表 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 表結(jié)構(gòu):
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 表結(jié)構(gòu):
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)
我們發(fā)現(xiàn),to_sql() 并沒有考慮將 emp_master 表字段的數(shù)據(jù)類型同步到目標表,而是簡單的區(qū)分數(shù)字型和字符型,這是第一個問題,第二個問題呢,目標表沒有 primary key。因為 pandas 定位是數(shù)據(jù)分析工具,數(shù)據(jù)源可以來自 CSV 這種文本型文件,本身是沒有嚴格數(shù)據(jù)類型的。而且,pandas 數(shù)據(jù) to_excel() 或者to_sql() 只是方便數(shù)據(jù)存放到不同的目的地,本身也不是一個數(shù)據(jù)庫升遷工具。
但如果我們需要嚴格保留原表字段的數(shù)據(jù)類型,以及同步 primary key,該怎么做呢?
使用 SQL 語句來創(chuàng)建表結(jié)構(gòu)
如果數(shù)據(jù)源本身是來自數(shù)據(jù)庫,通過腳本操作是比較方便的。如果數(shù)據(jù)源是來自 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 方式插入數(shù)據(jù)
to_sql() 方法的 if_exists 參數(shù)用于當目標表已經(jīng)存在時的處理方式,默認是 fail,即目標表存在就失敗,另外兩個選項是 replace 表示替代原表,即刪除再創(chuàng)建,append 選項僅添加數(shù)據(jù)。使用 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 參數(shù)指定字段的類型,然后在 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`);')
當然,如果數(shù)據(jù)源本身就是 mysql,當然不用大費周章來創(chuàng)建數(shù)據(jù)表的結(jié)構(gòu),直接使用 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()用法小結(jié)的文章就介紹到這了,更多相關pandas DataFrame.to_sql() 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Python數(shù)據(jù)分析之pandas比較操作
比較操作是很簡單的基礎知識,不過Pandas中的比較操作有一些特殊的點,本文介紹的非常詳細,對正在學習python的小伙伴們很有幫助.需要的朋友可以參考下2021-05-05
python自定義模塊使用.pth文件實現(xiàn)重用方式
這篇文章主要介紹了python自定義模塊使用.pth文件實現(xiàn)重用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-02-02
用Python實現(xiàn)換行符轉(zhuǎn)換的腳本的教程
這篇文章主要介紹了用Python實現(xiàn)換行符轉(zhuǎn)換的腳本的教程,代碼非常簡單,包括一個對操作說明的功能的實現(xiàn),需要的朋友可以參考下2015-04-04
Python反爬實戰(zhàn)掌握酷狗音樂排行榜加密規(guī)則
最新的酷狗音樂反爬來襲,本文介紹如何利用Python掌握酷狗排行榜加密規(guī)則,本章內(nèi)容只限學習,切勿用作其他用途?。。。?! 有需要的朋友可以借鑒參考下2021-10-10
Python matplotlib繪制圖形實例(包括點,曲線,注釋和箭頭)
這篇文章主要介紹了Python matplotlib繪制圖形實例(包括點,曲線,注釋和箭頭),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04
Python實現(xiàn)socket庫網(wǎng)絡通信套接字
socket又叫套接字,實現(xiàn)網(wǎng)絡通信的兩端就是套接字。分為服務器對應的套接字和客戶端對應的套接字,本文給大家介紹Python實現(xiàn)socket庫網(wǎng)絡通信套接字的相關知識,包括套接字的基本概念,感興趣的朋友跟隨小編一起看看吧2021-06-06
蘋果Macbook Pro13 M1芯片安裝Pillow的方法步驟
Pillow作為python的第三方圖像處理庫,提供了廣泛的文件格式支持,本文主要介紹了蘋果Macbook Pro13 M1芯片安裝Pillow,具有一定的參考價值,感興趣的可以了解一下2021-11-11

