1. 程式人生 > >sqlite3- SQLite資料庫的DB-API 2.0介面

sqlite3- SQLite資料庫的DB-API 2.0介面

sqlite3- SQLite資料庫的DB-API 2.0介面

SQLite是一個C庫,它提供了一個基於磁碟的輕量級資料庫,它不需要單獨的伺服器程序,並允許使用SQL查詢語言的非標準變體訪問資料庫。某些應用程式可以使用SQLite進行內部資料儲存。也可以使用SQLite對應用程式進行原型設計,然後將程式碼移植到更大的資料庫,如PostgreSQL或Oracle。

pysqlite由GerhardHäring編寫,提供符合DB-API 2.0規範的SQL介面 PEP 249

要使用該模組,必須首先建立一個Connection表示資料庫的物件。這裡的資料將儲存在/tmp/example

檔案中:

conn  =  sqlite3 .connect ('/ tmp / example'

您還可以提供特殊名稱:memory:以在RAM中建立資料庫。

獲得之後Connection,您可以建立一個Cursor 物件並呼叫其execute()方法來執行SQL命令:

c = conn.cursor()

# 建立表
c.execute('''create table stocks
(date text, trans text, symbol text,
 qty real, price real)''')

# 插入一行資料
c.execute("""insert into stocks
          values ('2006-01-05','BUY','RHAT',100,35.14)"""
) # 儲存(提交)變更(提交事務) conn.commit() # 如果事務完成,關閉游標 c.close()

通常,您的SQL操作需要使用Python變數中的值。你不應該使用Python的字串操作來組裝你的查詢,因為這樣做是不安全的; 它使您的程式容易受到SQL注入攻擊。

而是使用DB-API的引數替換。?在任何想要使用值的位置放置佔位符,然後提供值元組作為遊標execute()方法的第二個引數。(其他資料庫模組可能使用不同的佔位符,例如%s:1。)例如:

# 永遠不要這樣做 - 不安全!
symbol = 'IBM'
c.execute("... where symbol = '%s'"
% symbol) # 而是這樣做 t = (symbol,) c.execute('select * from stocks where symbol=?', t) # 多引數的示例 for t in [('2006-03-28', 'BUY', 'IBM', 1000, 45.00), ('2006-04-05', 'BUY', 'MSOFT', 1000, 72.00), ('2006-04-06', 'SELL', 'IBM', 500, 53.00), ]: c.execute('insert into stocks values (?,?,?,?,?)', t)

要在執行SELECT語句後檢索資料,可以將遊標視為迭代器,呼叫遊標的fetchone()方法以檢索單個匹配行,或呼叫fetchall()以獲取匹配行的列表。

此示例使用迭代器形式:

>>> c = conn.cursor()
>>> c.execute('select * from stocks order by price')
>>> for row in c:
...    print row
...
(u'2006-01-05', u'BUY', u'RHAT', 100, 35.14)
(u'2006-03-28', u'BUY', u'IBM', 1000, 45.0)
(u'2006-04-06', u'SELL', u'IBM', 500, 53.0)
(u'2006-04-05', u'BUY', u'MSOFT', 1000, 72.0)
>>>

模組函式和常量

  • sqlite3.``PARSE_DECLTYPES

    此常量用於與函式的detect_types引數 一起使用connect()。設定它使sqlite3模組解析它返回的每個列的宣告型別。它將解析出宣告型別的第一個單詞,即對於“整數主鍵”,它將解析出“整數”,或者對於“數字(10)”,它將解析出“數字”。然後對於該列,它將檢視轉換器字典並使用在那裡註冊的轉換器函式。

  • sqlite3.``PARSE_COLNAMES

    此常量用於與函式的detect_types引數 一起使用connect()。設定此選項會使SQLite介面解析它返回的每個列的列名。它將在那裡查詢形成[mytype]的字串,然後確定’mytype’是列的型別。它將嘗試在轉換器字典中找到“mytype”的條目,然後使用在那裡找到的轉換器函式來返回值。找到的列名Cursor.description 只是列名的第一個單詞,即如果你在SQL中使用類似的東西 ,那麼我們將解析所有內容,直到列名的第一個空白:列名只是“x”。'as "x [datetime]"'

  • sqlite3.``connectdatabase [,timeoutisolation_leveldetect_typesfactory ])

    開啟與SQLite資料庫檔案資料庫的連線。您可以使用 ":memory:"開啟與駐留在RAM而不是磁碟上的資料庫的資料庫連線。當多個連線訪問資料庫,並且其中一個程序修改資料庫時,SQLite資料庫將被鎖定,直到提交該事務為止。該超時引數指定連線應該多長時間等待鎖消失,直到引發異常。timeout引數的預設值為5.0(五秒)。對於isolation_level引數,請參閱物件的 Connection.isolation_level屬性Connection。SQLite本身僅支援TEXT,INTEGER,REAL,BLOB和NULL型別。如果您想使用其他型別,您必須自己新增對它們的支援。使用模組級函式註冊的 detect_types引數和使用自定義轉換器register_converter()可以輕鬆地執行此操作。detect_types預設值為0(即關閉,無型別檢測),可以將其設定為任意組合PARSE_DECLTYPESPARSE_COLNAMES開啟型別檢測上。預設情況下,sqlite3模組使用其Connection類進行連線呼叫。但是,您可以通過為工廠 引數提供類來替代Connection類並 connect()使用您的類。有關詳細資訊,請參閱本手冊的SQLite和Python型別部分。該sqlite3模組在內部使用語句快取來避免SQL解析開銷。如果要顯式設定為連線快取的語句數,可以設定cached_statements引數。當前實現的預設值是快取100個語句。

  • sqlite3.``register_convertertypenamecallable

    註冊callable以將資料庫中的bytestring轉換為自定義Python型別。將為typename型別的所有資料庫值呼叫callable 。賦予 函式的引數detect_typesconnect()進行型別檢測的工作方式。請注意,typename的大小寫和查詢中型別的名稱必須匹配!

  • sqlite3.``register_adapter型別可呼叫

    註冊callable以將自定義Python型別型別轉換為SQLite支援的型別之一。可呼叫的callable接受Python值作為單個引數,並且必須返回以下型別的值:int,long,float,str(UTF-8編碼),unicode或buffer。

  • sqlite3.``complete_statementsql

    返回True如果字串SQL包含由分號終止一個或多個完整的SQL語句。它不驗證SQL在語法上是否正確,只是沒有未閉合的字串文字,並且語句以分號結束。這可以用於為SQLite構建一個shell,如下例所示:

#最小SQLite shell的實驗研究

from pysqlite2 import dbapi2 as sqlite3

con = sqlite3.connect(":memory:")
con.isolation_level = None
cur = con.cursor()

buffer = ""

print "Enter your SQL commands to execute in SQLite."
print "Enter a blank line to exit."

while True:
    line = raw_input()
    if line == "":
        break
    buffer += line
    if sqlite3.complete_statement(buffer):
        try:
            buffer = buffer.strip()
            cur.execute(buffer)

            if buffer.lstrip().upper().startswith("SELECT"):
                print cur.fetchall()
        except sqlite3.Error, e:
            print "An error occurred:", e.args[0]
        buffer = ""

con.close()
  • sqlite3.``enable_callback_tracebacks

    預設情況下,您不會在使用者定義的函式,聚合,轉換器,授權器回撥等中獲得任何回溯。如果要除錯它們,可以使用標記為True 來呼叫此函式。之後,您將從回撥中獲得追溯sys.stderr。用於False再次禁用該功能。

連線物件

  • sqlite3.``Connection

    SQLite資料庫連線具有以下屬性和方法:

  • Connection.``isolation_level

    獲取或設定當前隔離級別。None用於自動提交模式或“DEFERRED”,“IMMEDIATE”或“EXCLUSIVE”之一。有關更詳細的說明,請參閱控制事務一節。

  • Connection.``cursor([cursorClass ])

    cursor方法接受一個可選引數cursorClass。如果提供,則必須是擴充套件的自定義遊標類sqlite3.Cursor

  • Connection.``commit()

    此方法提交當前事務。如果不呼叫此方法,commit()則從上次呼叫以來執行的任何操作都不會從其他資料庫連線中看到。如果您想知道為什麼沒有看到您寫入資料庫的資料,請檢查您是否忘記呼叫此方法。

  • Connection.``rollback()

    自上次呼叫以來,此方法回滾對資料庫的任何更改 commit()

  • Connection.``close()

    這將關閉資料庫連線。請注意,這不會自動呼叫commit()。如果您只是先關閉資料庫連線而不commit()先打電話,那麼您的更改將會丟失!

  • Connection.``executesql [,引數])

    這是一個非標準的快捷方式,它通過呼叫cursor方法建立一箇中間遊標物件,然後execute使用給定的引數呼叫遊標的 方法。

  • Connection.``executemanysql [,引數])

    這是一個非標準的快捷方式,它通過呼叫cursor方法建立一箇中間遊標物件,然後executemany使用給定的引數呼叫遊標的 方法。

  • Connection.``executescriptsql_script

    這是一個非標準的快捷方式,它通過呼叫cursor方法建立一箇中間遊標物件,然後executescript使用給定的引數呼叫遊標的 方法。

  • Connection.``create_functionnamenum_paramsfunc

    建立一個可以從SQL語句中以後使用下面的功能名稱的使用者定義函式的名稱num_params是函式接受的引數個數,func是Python可呼叫的,被稱為SQL函式。該函式可以返回SQLite支援的任何型別:unicode,str,int,long,float,buffer和None。

    例:建立一個可以從SQL語句中以後使用下面的功能名稱的使用者定義函式的名稱num_params是函式接受的引數個數,func是Python可呼叫的,被稱為SQL函式。該函式可以返回SQLite支援的任何型別:unicode,str,int,long,float,buffer和None。例:

from pysqlite2 import dbapi2 as sqlite3
import md5

def md5sum(t):
    return md5.md5(t).hexdigest()

con = sqlite3.connect(":memory:")
con.create_function("md5", 1, md5sum)
cur = con.cursor()
cur.execute("select md5(?)", ("foo",))
print cur.fetchone()[0]

Connection.``create_aggregatenamenum_paramsaggregate_class

建立使用者定義的聚合函式。

聚合類必須實現一個step方法,該方法接受引數num_params的數量,以及一個finalize將返回聚合的最終結果的方法。

finalize方法可以返回SQLite支援的任何型別:unicode,str,int,long,float,buffer和None。

from pysqlite2 import dbapi2 as sqlite3

class MySum:
    def __init__(self):
        self.count = 0

    def step(self, value):
        self.count += value

    def finalize(self):
        return self.count

con = sqlite3.connect(":memory:")
con.create_aggregate("mysum", 1, MySum)
cur = con.cursor()
cur.execute("create table test(i)")
cur.execute("insert into test(i) values (1)")
cur.execute("insert into test(i) values (2)")
cur.execute("select mysum(i) from test")
print cur.fetchone()[0]

Connection.``create_collation名稱可呼叫

建立具有指定名稱可呼叫的排序規則。callable將傳遞兩個字串引數。如果第一個排序低於第二個,則應返回-1;如果排序等於0,則返回0;如果第一個排序高於第二個,則返回1。請注意,這會控制排序(SQL中的ORDER BY),因此您的比較不會影響其他SQL操作。

請注意,callable將其引數作為Python位元組串,通常以UTF-8編碼。

以下示例顯示了對“錯誤方式”進行排序的自定義排序規則:

from pysqlite2 import dbapi2 as sqlite3

def collate_reverse(string1, string2):
    return -cmp(string1, string2)

con = sqlite3.connect(":memory:")
con.create_collation("reverse", collate_reverse)

cur = con.cursor()
cur.execute("create table test(x)")
cur.executemany("insert into test(x) values (?)", [("a",), ("b",)])
cur.execute("select x from test order by x collate reverse")
for row in cur:
    print row
con.close()

要刪除排序規則,請create_collation使用None作為callable呼叫:

con.create_collation("reverse", None)
  • Connection.``interrupt()

    您可以從其他執行緒呼叫此方法以中止可能在連線上執行的任何查詢。然後查詢將中止,呼叫者將獲得異常。

  • Connection.``set_authorizerauthorizer_callback

    此例程註冊回撥。每次嘗試訪問資料庫中表的列時都會呼叫回撥。SQLITE_OK如果允許訪問,SQLITE_DENY則應該返回回撥 ,如果整個SQL語句應該中止並出現錯誤,SQLITE_IGNORE並且該列應該被視為NULL值。這些常量在sqlite3模組中可用 。回撥的第一個引數表示要授權的操作型別。第二個和第三個引數將是引數或None 取決於第一個引數。第四個引數是資料庫的名稱(“main”,“temp”等)(如果適用)。第五個引數是負責訪問嘗試的最內層觸發器或檢視的名稱,或者 None此訪問嘗試是否直接來自輸入SQL程式碼。請參閱SQLite文件,瞭解第一個引數的可能值以及第二個和第三個引數的含義,具體取決於第一個引數。sqlite3模組中提供了所有必需的常量。

  • Connection.``get_limitlimit_id

    此例程返回由常量limit_id指定的限制的當前值。有關limit_id引數的可能值,請參閱SQLite文件。

  • Connection.``set_limitlimit_idnew_value

    此例程為常量limit_id指定的限制設定新值。有關limit_id引數的可能值,請參閱SQLite文件。

  • Connection.``set_progress_handler處理程式n

    此例程註冊回撥。 對SQLite虛擬機器的每n個指令呼叫回撥。如果要在長時間執行的操作期間從SQLite呼叫(例如更新GUI),這將非常有用。如果要清除以前安裝的任何進度處理程式,請使用Nonefor handler呼叫該方法。

  • Connection.``enable_load_extension啟用

    此例程允許/禁止SQLite引擎從共享庫載入SQLite擴充套件。SQLite擴充套件可以定義新功能,聚合或全新的虛擬表實現。一個眾所周知的擴充套件是與SQLite一起分發的全文搜尋擴充套件。

from pysqlite2 import dbapi2 as sqlite3

con = sqlite3.connect(":memory:")

# 載入全文搜尋副檔名
con.enable_load_extension(True)

# 或者您可以使用API呼叫載入副檔名
con.execute("select load_extension('./fts3.so')")

# 或者,可以使用API載入擴充套件。
call:
# con.load_extension("./fts3.so")

# 禁用擴充套件laoding
con.enable_load_extension(False)

# SQLite維基例項
con.execute("create virtual table recipe using fts3(name, ingredients)")
con.executescript("""
    insert into recipe (name, ingredients) values ('broccoli stew', 'broccoli peppers cheese tomatoes');
    insert into recipe (name, ingredients) values ('pumpkin stew', 'pumpkin onions garlic celery');
    insert into recipe (name, ingredients) values ('broccoli pie', 'broccoli cheese onions flour');
    insert into recipe (name, ingredients) values ('pumpkin pie', 'pumpkin sugar flour butter');
    """)
for row in con.execute("select rowid, name, ingredients from recipe where name match 'pie'"):
    print row
  • Connection.``load_extension路徑

    此例程從共享庫載入SQLite擴充套件。您必須先啟用擴充套件載入,enable_load_extension然後才能使用此例程。

  • Connection.``row_factory

    您可以將此屬性更改為可接受遊標和原始行作為元組的可呼叫物件,並返回實際結果行。這樣,您可以實現更高階的返回結果的方法,例如返回一個也可以按名稱訪問列的物件。例:

from pysqlite2 import dbapi2 as sqlite3

def dict_factory(cursor, row):
    d = {}
    for idx, col in enumerate(cursor.description):
        d[col[0]] = row[idx]
    return d

con = sqlite3.connect(":memory:")
con.row_factory = dict_factory
cur = con.cursor()
cur.execute("select 1 as a")
print cur.fetchone()["a"]
  • Connection.``text_factory

    使用此屬性可以控制為TEXT 資料型別返回的物件。預設情況下,此屬性設定為unicodesqlite3模組將返回Unicode物件TEXT。如果要返回位元組串,可以將其設定為str。出於效率原因,還有一種方法只返回非ASCII資料的Unicode物件,否則返回位元組串。要啟用它,請將此屬性設定為 sqlite3.OptimizedUnicode。您還可以將其設定為接受單個bytestring引數的任何其他可呼叫物件,並返回結果物件。請參閱以下示例程式碼以進行說明:

from pysqlite2 import dbapi2 as sqlite3

con = sqlite3.connect(":memory:")
cur = con.cursor()

# 建立表
con.execute("create table person(lastname, firstname)")

AUSTRIA = u"\xd6sterreich"

# 預設情況下,行返回為Unicode
cur.execute("select ?", (AUSTRIA,))
row = cur.fetchone()
assert row[0] == AUSTRIA

# 但我們可以讓pysqlite總是返回bytestrings ... 
con.text_factory = str
cur.execute("select ?", (AUSTRIA,))
row = cur.fetchone()
assert type(row[0]) == str
# 位元組串將被編碼在UTF-8中,除非您將儲存垃圾
# 到資料庫 ...
assert row[0] == AUSTRIA.encode("utf-8")

# 我們也可以實現一個定製的text_factory…
# 這裡我們從UTF-8解碼實現了一個忽略Unicode字元的方法。
con.text_factory = lambda x: unicode(x, "utf-8", "ignore")
cur.execute("select ?", ("this is latin1 and would normally create errors" + u"\xe4\xf6\xfc".encode("latin1"),))
row = cur.fetchone()
assert type(row[0]) == unicode
#pysqlite 提供了一個構建優化的 text_factory,它將返回位元組串。
#物件,如果資料僅在ASCII中,則返回Unicode物件。
con.text_factory = sqlite3.OptimizedUnicode
cur.execute("select ?", (AUSTRIA,))
row = cur.fetchone()
assert type(row[0]) == unicode

cur.execute("select ?", ("Germany",))
row = cur.fetchone()
assert type(row[0]) == str
  • Connection.``total_changes

    返回自開啟資料庫連線以來已修改,插入或刪除的資料庫行的總數。

  • Connection.``iterdump

    返回以SQL文字格式轉儲資料庫的迭代器。儲存記憶體資料庫以便以後恢復時很有用。此函式提供與sqlite3 shell中的.dump命令相同的功能。例:

#將檔案existing_db.db轉換為SQL轉儲檔案dump.sql
import sqlite3, os

con = sqlite3.connect('existing_db.db')
full_dump = os.linesep.join([line for line in con.iterdump()])
f = open('dump.sql', 'w')
f.writelines(full_dump)
f.close()

遊標物件

一個Cursor例項具有以下屬性和方法:

SQLite資料庫遊標具有以下屬性和方法:

  • Cursor.``close()

    現在關閉游標(而不是每次呼叫__del__)。從這一點開始,游標將無法使用; 如果使用遊標嘗試任何操作,將引發錯誤(或子類)異常。

  • Cursor.``executesql [,引數])

    執行SQL語句。SQL語句可以是引數化的(即佔位符而不是SQL文字)。該sqlite3模組支援兩種佔位符:問號(qmark樣式)和命名佔位符(命名樣式)。此示例顯示如何使用qmark樣式的引數:

from pysqlite2 import dbapi2 as sqlite3

con = sqlite3.connect("mydb")

cur = con.cursor()

who = "Yeltsin"
age = 72

cur.execute("select name_last, age from people where name_last=? and age=?", (who, age))
print cur.fetchone()

此示例顯示如何使用命名樣式:

from pysqlite2 import dbapi2 as sqlite3

con = sqlite3.connect("mydb")

cur = con.cursor()

who = "Yeltsin"
age = 72

cur.execute("select name_last, age from people where name_last=:who and age=:age",
    {"who": who, "age": age})
print cur.fetchone()
  • Cursor.``executemanysqlseq_of_parameters

    對序列sql中找到的所有引數序列或對映執行SQL命令。該sqlite3模組還允許使用 迭代器產生引數而不是序列。

from pysqlite2 import dbapi2 as sqlite3

class IterChars:
    def __init__(self):
        self.count = ord('a')

    def __iter__(self):
        return self

    def next(self):
        if self.count > ord('z'):
            raise StopIteration
        self.count += 1
        return (chr(self.count - 1),) #這是一個 1-tuple

con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.execute("create table characters(c)")

theIter = IterChars()
cur.executemany("insert into characters(c) values (?)", theIter)

cur.execute("select c from characters")
print cur.fetchall()

這是使用生成器的簡短示例:

from pysqlite2 import dbapi2 as sqlite3

def char_generator():
    import string
    for c in string.letters[:26]:
        yield (c,)

con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.execute("create table characters(c)")

cur.executemany("insert into characters(c) values (?)", char_generator())

cur.execute("select c from characters")
print cur.fetchall()

Cursor.``executescriptsql_script

這是一次執行多個SQL語句的非標準方便方法。它首先發出一個COMMIT語句,然後執行它作為引數獲取的SQL指令碼。

sql_script可以是bytestring或Unicode字串。

例:

from pysqlite2 import dbapi2 as sqlite3

con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.executescript("""
    create table person(
        firstname,
        lastname,
        age
    );

    create table book(
        title,
        author,
        published
    );

    insert into book(title, author, published)
    values (
        'Dirk Gently''s Holistic Detective Agency',
        'Douglas Adams',
        1987
    );
    """)
  • Cursor.``fetchone()

    獲取查詢結果集的下一行,返回單個序列,或者None當沒有更多資料可用時。

  • Cursor.``fetchmany([size = cursor.arraysize ])

    獲取查詢結果的下一組行,返回一個列表。當沒有更多行可用時,返回空列表。每次呼叫獲取的行數由size引數指定。如果未給出,則遊標的arraysize確定要獲取的行數。該方法應嘗試獲取size引數指示的行數。如果由於指定的行數不可用而無法執行此操作,則可能返回的行數較少。請注意,size引數涉及效能方面的考慮因素。為獲得最佳效能,通常最好使用arraysize屬性。如果使用size引數,那麼最好從一次fetchmany()呼叫到下一次呼叫保留相同的值。

  • Cursor.``fetchall()

    獲取