張小鳳 高正明
摘要:本文主要論述了基于python的SQLite數(shù)據(jù)庫數(shù)據(jù)存儲(chǔ)原理、過程和用途。具體以SQLite3為例,將文本數(shù)據(jù)存儲(chǔ)的過程進(jìn)行了闡述和說明。
關(guān)鍵詞:反應(yīng)截面、Python、數(shù)據(jù)存儲(chǔ)、SQLite
引言:
在科研學(xué)習(xí)過程中,為了防止數(shù)據(jù)被反復(fù)抓取,我們通常需要運(yùn)用Python代碼從網(wǎng)站上爬取相關(guān)數(shù)據(jù),則需要將數(shù)據(jù)保存到本地,其中最常用的方式就是將數(shù)據(jù)按照設(shè)計(jì)的數(shù)據(jù)格式保存到指定的文件中,其中常用的數(shù)據(jù)類型為文本文檔txt、表格類文件csv、 excel 等。此外,還可以將數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫(例如SQLite3、MySQL等)中,以便能夠便捷讀取及管理數(shù)據(jù)。
SQLite相比于其他數(shù)據(jù)庫,其不需要單獨(dú)的進(jìn)行安裝或者管理服務(wù),即不需要配置,只需要程序調(diào)用即可,不要求為該數(shù)據(jù)庫生成一個(gè)單獨(dú)的服務(wù)器進(jìn)程且不需要為其單獨(dú)配置可操作的系統(tǒng),及不需要配置服務(wù)器;其次,SQLite數(shù)據(jù)庫的存儲(chǔ)文件相比于其他存儲(chǔ)文件,其占用磁盤的空間很小,屬于輕量級(jí)的文件,且可以在多個(gè)跨平臺(tái)的系統(tǒng)中進(jìn)行使用和處理,即該文件不依賴多余的硬件或者軟件配置,就可以實(shí)現(xiàn)自給自足;另外,對(duì)于ACID,SQLite數(shù)據(jù)庫的訪問和設(shè)置均是完全兼容的,即對(duì)于同一個(gè)SQLite數(shù)據(jù)庫文件而言,它容許多個(gè)程序或者程序進(jìn)程、線程進(jìn)行安全管理訪問;除此之外,SQLite采用的是 ANSI-C 進(jìn)行編輯的,同時(shí)為了能夠更方便于用戶操作,它提供了簡(jiǎn)潔明了的API,同時(shí)為了方便用戶查詢數(shù)據(jù)庫的信息,SQL92(SQL2)標(biāo)準(zhǔn)中大部分的查詢功能均被支持使用。
因?yàn)镻ython 2.5x及以上的版本均內(nèi)置了SQLite3數(shù)據(jù)庫引擎,因此直接輸入命令“import sqlite3”即可使用。鑒于SQLite3和Python相結(jié)合的優(yōu)點(diǎn),本文主要闡述如何利用Python將文本數(shù)據(jù)錄入SQLite3數(shù)據(jù)庫。
1、python的操作步驟
① 首先創(chuàng)建一個(gè)與數(shù)據(jù)庫文件的連接對(duì)象connection,即利用sqlite3.open(),函數(shù);
② 其次創(chuàng)建光標(biāo)對(duì)象cursor,即利用connection.cursor()函數(shù);
③ 然后使SQL語句將會(huì)被執(zhí)行,利用cursor.execute()函數(shù);
④ 再利用connection.commit()函數(shù)提交當(dāng)前事務(wù),或利用cursor.fetchall(),獲得查詢結(jié)果;
⑤ 最后將與數(shù)據(jù)庫文件的連接關(guān)閉,即利用connection.close()。
2、具體步驟
2.1、逐行讀取指定路徑下文件的文件內(nèi)容
通過采用with語句和open語句的結(jié)合,可以安全地實(shí)現(xiàn)對(duì)文件的打開操作,并利用readlines()函數(shù)以便對(duì)文件的每行內(nèi)容進(jìn)行快速便捷讀取,即對(duì)all的數(shù)據(jù)進(jìn)行拆分。
with open("eedl.all") as f:
text = f.readlines()
2.2、對(duì)數(shù)據(jù)進(jìn)行解析,判斷當(dāng)前行是不是目標(biāo)數(shù)據(jù)行
文件包含說明信息和反應(yīng)截面數(shù)據(jù),如下圖2-1 钚元素與光子的相互作用截面數(shù)據(jù)庫(摘錄)所示,它包含的是說明、解釋型信息。第一列為MF號(hào),第二列為MT號(hào),第三列為該MT號(hào)下的截面數(shù)據(jù)占多少行。
其中,其對(duì)應(yīng)的反應(yīng)截面數(shù)據(jù)如下圖2-2 钚元素與光子相互作用截面數(shù)據(jù)庫所示,從左至右第1、3、5列為能量點(diǎn),即下圖中方框所示,第2、4、6列分別為1、3、5列的能量點(diǎn)對(duì)應(yīng)的截面數(shù)據(jù),即下圖中橢圓所示。
通過分析數(shù)據(jù)的存儲(chǔ)格式和目標(biāo)數(shù)據(jù)與非目標(biāo)數(shù)據(jù)的差異,發(fā)現(xiàn)目標(biāo)數(shù)據(jù)在去除符號(hào)后,均為數(shù)字格式,所以首先對(duì)當(dāng)前行數(shù)據(jù)進(jìn)行預(yù)處理:去除當(dāng)前行字符串中的符號(hào)元素。然后嘗試將字符串格式轉(zhuǎn)換為float數(shù)據(jù)類型,當(dāng)轉(zhuǎn)換失敗,觸發(fā)異常,則說明當(dāng)前行數(shù)據(jù)不是目標(biāo)數(shù)據(jù),則繼續(xù)遍歷處理下一行,如圖2-3所示。
2.3、目標(biāo)數(shù)據(jù)行數(shù)據(jù)解析
解析MAT、MF、MT數(shù)據(jù):MF號(hào)和MT號(hào)組合是倒數(shù)第二列,MAT號(hào)是倒數(shù)第三列,并且 MT就是3位,但是也可能會(huì)出現(xiàn)MAT號(hào)與MF和MT號(hào)粘連且與第六列的數(shù)據(jù)也粘連(如圖2-4所示)或者僅MAT號(hào)與MF和MT號(hào)粘連(如圖2-5所示)的現(xiàn)象。當(dāng)MAT號(hào)與MF和MT號(hào)粘連且與第六列的數(shù)據(jù)也粘連時(shí),共占字符大于9,其中MT號(hào)占最后三個(gè)字符,MF號(hào)占倒數(shù)第五至第三的字符,MAT占倒數(shù)第九至第五的字符;當(dāng)僅MAT號(hào)與MF和MT號(hào)粘連時(shí),第二列為MF和MT號(hào)共占字符數(shù)大于等于5,其中MT號(hào)占最后三個(gè)字符,MF號(hào)占倒數(shù)5至3位的字符,MAT號(hào)占倒數(shù)0至5位;當(dāng)MAT號(hào)與MF和MT號(hào)不粘連時(shí)(如圖2-6所示),MAT為倒數(shù)第三列,MF和MT為倒數(shù)第二列,其中MT占后面三位,MF占前面兩位。因此,目標(biāo)數(shù)據(jù)行數(shù)據(jù)解析如圖2-7所示。
因?yàn)槲覀兯枰臄?shù)據(jù)只有文件中每一行的前六個(gè)數(shù)據(jù),后面的數(shù)據(jù)為說明語句,因此對(duì)前六個(gè)數(shù)據(jù)進(jìn)行拆分。由于第六列數(shù)據(jù)可能會(huì)出現(xiàn)與第七列說明語句粘連的現(xiàn)象,所以,按照“ ”進(jìn)行分割后,對(duì)于前5個(gè)數(shù)據(jù),直接判斷為需要的數(shù)據(jù),對(duì)于第6個(gè)數(shù)據(jù),當(dāng)其長(zhǎng)度小于等于10,直接判斷為需要的數(shù)據(jù)。當(dāng)其第一位為“-”,且長(zhǎng)度為11,直接判斷為需要的數(shù)據(jù)。當(dāng)?shù)谝晃粸椤?”且長(zhǎng)度大于11,則在第11位處進(jìn)行分割。當(dāng)?shù)谝晃徊皇恰?”,且位數(shù)大于10,則再第10位進(jìn)行分割。
一行六個(gè)數(shù)據(jù),分為三組(能量點(diǎn)--對(duì)應(yīng)截面),存儲(chǔ)時(shí)是將能量點(diǎn)與對(duì)應(yīng)的截面同時(shí)存放,每一行三組數(shù)據(jù),即存放三次。因?yàn)槟芰繛?的粒子是不存在的,所以應(yīng)該舍去能量點(diǎn)為0的對(duì)應(yīng)數(shù)據(jù),即去除異常元素。
在存放時(shí),需要判斷“energy”是否為0,當(dāng)“energy”不為零時(shí),則將“energy”和對(duì)應(yīng)的截面數(shù)據(jù)存放在數(shù)據(jù)庫。
2.4、數(shù)據(jù)入庫
為了保證數(shù)據(jù)元素的純凈,首先需要檢測(cè)將要被創(chuàng)建的數(shù)據(jù)庫文件是否已經(jīng)存在,如果不存在,則創(chuàng)建數(shù)據(jù)庫文件,如果存在,則刪除原來的數(shù)據(jù)庫文件。
在創(chuàng)建數(shù)據(jù)庫后,數(shù)據(jù)庫需要初始化:即創(chuàng)建表,如圖2-8所示。
當(dāng)對(duì)數(shù)據(jù)庫的表創(chuàng)建完畢后,即實(shí)現(xiàn)了創(chuàng)建相應(yīng)數(shù)據(jù)庫的操作,此時(shí)當(dāng)前目錄下可以找到對(duì)應(yīng)的數(shù)據(jù)庫文件,然后插入數(shù)據(jù)。
2.5、數(shù)據(jù)處理
在將數(shù)據(jù)轉(zhuǎn)變成string變量時(shí),數(shù)據(jù)末尾可能會(huì)出現(xiàn)多個(gè)0,為了數(shù)據(jù)的直觀和美觀,將末尾多余的0去除。在數(shù)據(jù)轉(zhuǎn)成string變量后,查找nRet中的“.”位置,然后記錄nRet的長(zhǎng)度。然后判斷數(shù)據(jù)是否為小數(shù),nPosPoint=1則說明nRet中沒有“.”,可以直接存儲(chǔ);nPosNotZero>1則說明nRet中有“.”,可能需要尾綴去零處理。
利用倒敘循環(huán)遍歷nRet中小數(shù)點(diǎn)后從左至右連續(xù)的零的情況,即從右至左到小數(shù)點(diǎn)后一位依次判斷該位是否為零。參考代碼如下:
for i in range(nLen-1, nPosPoint-1, -1):
if nRet[i] != "0":
nPosNotZero = i
Break
2.6、查詢和確認(rèn)數(shù)據(jù)
最后可以導(dǎo)入sqlite3模塊,然后連接數(shù)據(jù)庫利用sql語句查詢和確認(rèn)數(shù)據(jù)入庫的情況。
3、結(jié)束語
本文的數(shù)據(jù)存儲(chǔ)過程適用于文本數(shù)據(jù)的存儲(chǔ),以實(shí)現(xiàn)數(shù)據(jù)共享、減少數(shù)據(jù)的冗余度、同時(shí)保持?jǐn)?shù)據(jù)的獨(dú)立性、實(shí)現(xiàn)數(shù)據(jù)集中控制,并確保數(shù)據(jù)的一致性和可維護(hù)性。
【參考文獻(xiàn)】:
[1]Python操作SQLite數(shù)據(jù)庫[J].朱純陽.計(jì)算機(jī)軟件與計(jì)算機(jī)應(yīng)用.2015(15)
[2]淺談SQLite數(shù)據(jù)庫技術(shù)在Android平臺(tái)的應(yīng)用,[J].唐磊.計(jì)算機(jī)軟件與計(jì)算機(jī)應(yīng)用.2014(09)