Python常用模塊11-python的csv模塊

一.CSV模塊介紹

CSV (Comma Separated Values) 格式是電子表格和數(shù)據(jù)庫(kù)中最常見(jiàn)的輸入、輸出文件格式。在 RFC 4180規(guī)范推出的很多年前,CSV 格式就已經(jīng)被開始使用了,由于當(dāng)時(shí)并沒(méi)有合理的標(biāo)準(zhǔn)米者,不同應(yīng)用程序讀寫的數(shù)據(jù)會(huì)存在細(xì)微的差別。這種差別讓處理多個(gè)來(lái)源的 CSV 文件變得困難。但盡管分隔符會(huì)變化蔓搞,此類文件的大致格式是相似的胰丁,所以編寫一個(gè)單獨(dú)的模塊以高效處理此類數(shù)據(jù),將程序員從讀寫數(shù)據(jù)的繁瑣細(xì)節(jié)中解放出來(lái)是有可能的喂分。

csv模塊定義的函數(shù):

函數(shù)名 函數(shù)用途
csv.reader(csvfile, dialect='excel', **fmtparams) 返回一個(gè) reader 對(duì)象锦庸,該對(duì)象將逐行遍歷 csvfile
csv.writer(csvfile, dialect='excel', **fmtparams) 返回一個(gè) writer 對(duì)象,該對(duì)象負(fù)責(zé)將用戶的數(shù)據(jù)在給定的文件類對(duì)象上轉(zhuǎn)換為帶分隔符的字符串
csv.register_dialect(name[, dialect[, **fmtparams]]) 將 name 與 dialect 關(guān)聯(lián)起來(lái)妻顶。name 必須是字符串酸员。
csv.unregister_dialect(name) 從變種注冊(cè)表中刪除 name 對(duì)應(yīng)的變種。
csv.get_dialect(name) 返回 name 對(duì)應(yīng)的變種讳嘱。
csv.list_dialects() 返回所有已注冊(cè)變種的名稱
csv.field_size_limit([new_limit]) 返回解析器當(dāng)前允許的最大字段大小

csv模塊定義的類:

類名 類描述
class csv.DictReader 創(chuàng)建一個(gè)對(duì)象幔嗦,其操作類似于常規(guī) reader 但會(huì)將每行中的信息映射到一個(gè) OrderedDict,其中的鍵由可選的 fieldnames 形參給出沥潭。
class csv.DictWriter 創(chuàng)建一個(gè)對(duì)象邀泉,該對(duì)象在操作上類似常規(guī) writer,但能將字典映射到輸出行
class csv.Dialect Dialect 類是主要依賴于其屬性的容器類钝鸽,用于將定義好的參數(shù)傳遞給特定的 readerwriter 實(shí)例汇恤。
class csv.excel excel 類定義了 Excel 生成的 CSV 文件的常規(guī)屬性。它在變種注冊(cè)表中的名稱是 'excel'
class csv.excel_tab excel_tab 類定義了 Excel 生成的拔恰、制表符分隔的 CSV 文件的常規(guī)屬性因谎。它在變種注冊(cè)表中的名稱是 'excel-tab'
class csv.unix_dialect unix_dialect 類定義了在 UNIX 系統(tǒng)上生成的 CSV 文件的常規(guī)屬性颜懊,即使用 '\n' 作為換行符财岔,且所有字段都有引號(hào)包圍。
class csv.Sniffer Sniffer 類用于推斷 CSV 文件的格式河爹。

csv模塊定義了以下常量:

csv.QUOTE_ALL 指示 writer 對(duì)象給所有字段加上引號(hào)
csv.QUOTE_MINIMAL 指示 writer 對(duì)象僅為包含特殊字符(例如 定界符匠璧、引號(hào)字符行結(jié)束符 中的任何字符)的字段加上引號(hào)。
csv.QUOTE_NONNUMERIC 指示 writer 對(duì)象為所有非數(shù)字字段加上引號(hào)咸这。
csv.QUOTE_NONE 指示 writer 對(duì)象不使用引號(hào)引出字段夷恍。

csv模塊定義了以下異常:
exception csv.Error
該異常可能由任何發(fā)生錯(cuò)誤的函數(shù)拋出媳维。

二.csv模塊實(shí)例

2.1 將mysql查詢到的數(shù)據(jù)導(dǎo)出到本地csv文件

代碼:

import csv
import pymysql

# 創(chuàng)建mysql連接
conn = pymysql.connect(host='localhost', port=3306, user='root', passwd='abc123',db='zqs')
cursor = conn.cursor()

sql1 = "select empno,ename , mgr,hiredate from emp where 1 = 1"
headers = ["empno","ename","mgr","hiredate"]

cursor.execute(sql1)

rows = cursor.fetchall()

with open('E:\python\emp.csv', 'w', newline='') as csvfile:
    my_csv_write = csv.writer(csvfile, delimiter=',', quoting=csv.QUOTE_MINIMAL)
    my_csv_write.writerow(headers)
    my_csv_write.writerows(rows)

conn.commit()

# 關(guān)閉連接
cursor.close()
conn.close()

測(cè)試記錄:
如下查看可得知酿雪,數(shù)值、字符侄刽、日期以及空值都正常導(dǎo)出到了csv文件

image.png

2.2 將本地csv文件導(dǎo)入到mysql數(shù)據(jù)庫(kù)

對(duì)于CSV中空值的處理
數(shù)值型空值执虹,必須是 %s 而不能使用 '%s'
字符型空值以及時(shí)間類型空值,必須是 %s 而不能使用 '%s',但是錄入其它非空的字符唠梨,又必須用'%s'

用excel打開csv文件截圖:


image.png

從上圖可以看到 ename列是字符型空值,mgr侥啤、comm列是數(shù)值型空值当叭,hiredate是日期型空值
Python代碼:
db_setting.py

# 存儲(chǔ)數(shù)據(jù)庫(kù)信息
# 創(chuàng)建一個(gè)列表嵌套列表,存儲(chǔ)數(shù)據(jù)庫(kù)信息
# 依次是 數(shù)據(jù)庫(kù)備注茬故、ip、端口蚁鳖、磺芭、用戶名、密碼醉箕、登陸數(shù)據(jù)庫(kù)名

mysql_msg = [['本地mysql', 'localhost', 3306 , 'root', 'abc123', 'zqs'],
             ['遠(yuǎn)程mysql', '10.31.1.123', 3306, 'root', 'abc123', 'test']
             ]

mysql_test3.py

import pymysql, datetime
import csv
import db_setting
import math
from numpy import nan as NaN

class mysql_class(object):
    """對(duì)mysql的操作創(chuàng)建一個(gè)類"""
    def __init__(self, name):
        self.name = name

    def login_mysql(self):
        """獲取mysql的登陸信息"""
        mysql_msg = db_setting.mysql_msg
        name = self.name
        for i in range(0,len(mysql_msg) ):
            exec_db = mysql_msg[i]
            if name == exec_db[0]:
                # 根據(jù)輸入連接數(shù)據(jù)庫(kù)
                return exec_db
                # conn = pymysql.connect(host=exec_db[1], port=exec_db[2], user=exec_db[3], passwd=exec_db[4],db=exec_db[5])
            else:
                pass

    def csv_insert_mysql(self):
        """將csv的文件錄入到mysql"""

        exec_db = mysql_class.login_mysql(self)
        conn = pymysql.connect(host=exec_db[1], port=exec_db[2], user=exec_db[3], passwd=exec_db[4], db=exec_db[5] ,charset='utf8')

        cursor = conn.cursor()

        # 測(cè)試了數(shù)值類型還是會(huì)存在問(wèn)題, yyyy/mm/dd 這類時(shí)間格式測(cè)試了也不會(huì)有問(wèn)題的
        # 數(shù)值型空值钾腺,必須是 %s 而不能使用 '%s'
        # 字符型空值以及時(shí)間類型空值,必須是 %s 而不能使用 '%s',但是錄入其它非空的字符讥裤,又必須用'%s'
        sql = ""
        sql1 = "insert into emp_csv(empno, ename, job, mgr, hiredate, sal, comm, deptno) values ('%s', %s, '%s', %s, '%s', '%s', %s, '%s') "
        sql2 = "insert into emp_csv(empno, ename, job, mgr, hiredate, sal, comm, deptno) values ('%s', '%s', '%s', %s, '%s', '%s', %s, '%s') "

        sql3 = "insert into emp_csv(empno, ename, job, mgr, hiredate, sal, comm, deptno) values ('%s', '%s', '%s', %s, %s, '%s', %s, '%s') "


        filename = 'E:/python/file_test/emp_csv_2.csv'

        with open(filename, 'r') as f:
            reader = csv.reader(f)
            # print(type(reader))

            for i, row in enumerate(reader):
                # 剔除第一行的列頭
                if i > 0:
                    empno = row[0]

                    if  row[1]:
                        ename = row[1]
                    else:
                        ename = 'NULL'

                    job = row[2]

                    if  row[3]:
                        mgr = row[3]
                    else:
                        mgr = 'NULL'

                    if  row[4]:
                        hiredate = row[4]
                    else:
                        hiredate = 'NULL'

                    sal = row[5]

                    if row[6]:
                        comm = row[6]
                    else:
                        comm =  'NULL'

                    deptno = row[7]

                    print(empno, ename, job, mgr , hiredate, sal, comm , deptno)

                    # 遍歷列表,循環(huán)錄入數(shù)據(jù)
                    if not row[1]:
                        sql = sql1

                    if not row[4]:
                        sql = sql3

                    # 如果存在兩列同時(shí)為null的情況,還得繼續(xù)增加判斷條件

                    if row[1]:
                        if row[4]:
                            sql = sql2

                    cursor.execute(sql % (empno, ename, job, mgr, hiredate, sal, comm, deptno))



            conn.commit()

            # 關(guān)閉連接
            cursor.close()
            conn.close()


if __name__ == '__main__':
    my_class1 = mysql_class('本地mysql')

    my_class1.csv_insert_mysql()

參考:

1.https://docs.python.org/zh-cn/3.6/library/csv.html#

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末放棒,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子己英,更是在濱河造成了極大的恐慌间螟,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件损肛,死亡現(xiàn)場(chǎng)離奇詭異厢破,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)治拿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門摩泪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人劫谅,你說(shuō)我怎么就攤上這事见坑。” “怎么了同波?”我有些...
    開封第一講書人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵鳄梅,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我未檩,道長(zhǎng)戴尸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任冤狡,我火速辦了婚禮孙蒙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘悲雳。我一直安慰自己挎峦,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開白布合瓢。 她就那樣靜靜地躺著坦胶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上顿苇,一...
    開封第一講書人閱讀 51,698評(píng)論 1 305
  • 那天峭咒,我揣著相機(jī)與錄音,去河邊找鬼纪岁。 笑死凑队,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的幔翰。 我是一名探鬼主播漩氨,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼或粮,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼铡俐!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起针史,我...
    開封第一講書人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤贡定,失蹤者是張志新(化名)和其女友劉穎赋访,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缓待,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蚓耽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了旋炒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片步悠。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖瘫镇,靈堂內(nèi)的尸體忽然破棺而出鼎兽,到底是詐尸還是另有隱情,我是刑警寧澤铣除,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布谚咬,位于F島的核電站,受9級(jí)特大地震影響尚粘,放射性物質(zhì)發(fā)生泄漏择卦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一郎嫁、第九天 我趴在偏房一處隱蔽的房頂上張望秉继。 院中可真熱鬧,春花似錦泽铛、人聲如沸尚辑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)杠茬。三九已至月褥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間澈蝙,已是汗流浹背吓坚。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留灯荧,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓盐杂,卻偏偏與公主長(zhǎng)得像逗载,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子链烈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容