pysqlite
2019獨角獸企業重金招聘Python工程師標準>>>
我對pysqlite的一些了解
大約是一年半或者是兩年前的樣子,在那段時間里,我似乎特別癡迷于各種數據庫以及相關的技術。其間看了不少書,可能是平常工作接觸的多是?sqlserver?的緣故,我本人對其反而不是特別的感冒,所以看的多是關于?postgresql?和?oracle?的,尤其是前者。記得當時用的是一臺?celeron1.7G?、內存?256MB?的方正電腦,安裝這些軟件讓電腦變得非常的慢,終于在一次忍無可忍的僵死之后,我卸載了所有這些龐然大物。
之后臺里引進了一臺用于上下班記錄的打卡機,為了方便統計遲到早退,我用?perl/tk?寫了一個采集整理程序,后臺用到了?sqlite,這也是我和?sqlite?的初次邂逅。
至于對?python?,不好意思地說,我一直抱著騎墻的態度。如果?perl?可以解決的,我是斷然不會用?python?的,這一切直到我對?poe的幻想破滅為止。原先我是期待用?poe?來作為多線程的替代,可事實還是向著相反的方向發展。
sqlite?是一個嵌入式的數據庫,也就是說沒有獨立的維護進程,所有的維護都來自于程序本身。麻雀雖小,五臟俱全,?sqlite?實現了多數?sql-92?的標準,比如說?transaction?、?trigger?和復雜的查詢等。
有很多介紹的書籍,記得有一本?apress?出版的《?The?difinitive?guide?to?sqlite?》,有毛?500?面的樣子,用來介紹一個嵌入式數據庫,著實有點長了,當然對于初學者是有其存在的價值的。
而?pysqlite?則是一個?sqlite?為?python?提供的?api?接口,它讓一切對于?sqlite?的操作都變得異常簡單。?userguide?并不長,但是基本上都說到點子上了,不過這里還是要對其提一下幾個要點。事實上我個人認為,理解了這幾點就完全足夠了。
“?from?pysqlite2?import?dbapi2?as?sqlite?”,???這就是一切的起源。
下面是一個涉及到我即將介紹的幾點的示例程序,內容很簡單,就是將一個?Point?對象存入?sqlite?建立的內存數據庫中,然后原封不動地返回出來。
from?pysqlite2?import?dbapi2?as?sqlite
class?Point(object):
???def?__init__(self,?x,?y):
??????self.x,?self.y?=?x,?y
???def?__conform__(self,?protocol):
??????if?protocol?is?sqlite.PrepareProtocol:
??????????return?"%d;%d"?%?(self.x,?self.y)
?
def?adapt_converter(point):
???return?Point(*[int(x)?for?x?in?point.split(";")])
sqlite.register_converter('point',?adapt_converter)
con=sqlite.connect(":memory:",detect_types=?sqlite.PARSE_COLNAMES)
cur?=?con.cursor()
cur.execute('select???as?"a?[point]"',?(Point(2,?3),?))
print?type(cur.fetchone()[0])
首先要做一些準備工作,因為?sqlite?不是什么?python?對象都能夠接受的?,?為此需要一些必要的轉換。這個例子里,?sqlite?就像是一個汽車維修站。在站里,為了維修,汽車被拆成了個個零件,等出站時又被組裝成了一輛汽車。
第一步是聲明一個?Point?類。這個類除了初始化函數?__init__?之外,還有一個兩參量的函數?__conform__?,?sqlite?在檢查存入數據庫對象的時候會檢查是否存在該函數,如果存在,則將該函數返回的值替代對象本身存入數據庫。可以說這是一個轉換器,將?python對象轉換為?sqlite?允許接納對象,即?Null?、?Integer?、?Real?、?Text?和?Blob?其中之一。在這里,顯然?sqlite?是無法接納Point?這個類所建立的?Point(2,3)?對象的,所以通過?__conform__?,實際將存入內容為“?2;3?”的文本。
使用“?sqlite.register_adapter(Point,?lambda?p?=?point?:?“%d;%d”?%?p.x,?p.y)?”,在?sqlite?中注冊一個適配器也可以完成轉換的功能,但是我個人認為這樣比較麻煩,不如寫在類里來得清楚。
在處理完了?Point?類之后,為了使文本“?2;3?”在從數據庫取出時能轉換為?Point?對象,還需要用“sqlite.register_converter?”注冊一個叫“?adapt_converter?”的轉換器。
這樣一條拆卸組裝的流水線就完成了。
實際使用到的只有兩樣東西,一是數據庫連接對象?con?,還有一個就是用來執行命令并返回結果(有必要的話)的游標對象?cur?,它是由?con?對象產生的。
為了使?sqlite?意識到它正在處理的表中的某一列是已注冊需要轉換的“?phone?”,我們需要在建立表的時候聲明該列的屬性,或者在查詢的時候顯示地表明該列的屬性。對于前者,建立?con?對象是應將?detect_types?設置為?sqlite.PARSE_DELTYPES?;后者,則是設置為?sqlite.PARSE_COLNAMES?。這里,因為使用的是一個臨時表,所以只能使用后者的設置辦法。
事實上,“?select???as?……?”這句包含了兩個方面的內容,首先它將?Point(2,?3)?存入了臨時表中,這涉及到了?Phone?對象到文本的轉換。之后,再將文本數據從臨時表中取出,又用到了文本到?Phone?的反轉換。
下面是一種淺顯而羅嗦的寫法:
cur.execute("create?table?temp(t)")
cur.execute("insert?into?temp?values?(?)",?(Point(2,?3),))
cur.execute('select???as?"a?[point]"?from?temp')
最后,打印從?sqlite?中取出的對象類型,內容為“?<class?'__main__.Point'>?”。
以上這些,可以總結為兩點:有必要的話,做好轉換;建立?con?和?cur?。理解了這些,差不多就能用?pysqlite?了。當然如果要做工程、寫程序還需要很多的其他知識,至少數據庫設計這方面的內容是要看一下的。
posted on 2008-07-04 18:26?gyn_tadao?閱讀(1571)?評論(1)??編輯?收藏?引用?所屬分
轉載于:https://my.oschina.net/zhengyijie/blog/158945
總結
- 上一篇: 程序员的职业素养-读书笔记
- 下一篇: jqplot学习笔记