Python 中 sqlite3 模組使用小記

2021-09-16 19:45:48 字數 3249 閱讀 6753

前記

python 的標準庫中包含了對 sqlite 這個輕巧的資料庫的支援模組,也就是 sqlite3 模組。sqlite 資料庫的好處我就不多說了,小型而強大,適合很多小型或者中型的資料庫應用。最近在使用 sqlite3 模組遇到一些問題,解決了,順便就記下來。

問題sqlite3 模組的使用很簡單,如下這段測試**,建立乙個 person 資料表然後進行一次資料庫查詢操作。

#!/usr/bin/env pypthon

#_*_ coding: utf-8 _*_

import sqlite3

schema = """

create table person (

p_id int,

p_name text

)"""

def init():

data = [(1, 'tony'), (1, 'jack')]

conn = sqlite3.connect(':memory:')

c = conn.cursor()

try:

c.execute(schema)

for person in data:

c.execute('insert into person values(?, ?)', person)

conn.commit()

except sqlite3.error as e:

print 'error!', e.args[0]

return conn

if __name__ =='__main__':

conn = init()

c = conn.cursor()

#do a query.

c.execute('select * from person where p_name = ?', 'tony')

person = c.fetchone()

print person

traceback (most recent call last):

file "sqlite3_test.py", line 32, in c.execute('select * from person where p_name = ?', 'tony')

sqlite3.programmingerror: incorrect number of bindings supplied. the current statement uses 1, and there are 4 supplied.

很莫名奇妙是不?明明我提供的佔位符?繫結只有乙個字串引數,可是卻說我提供了四個。再看仔細點,說提供了四個,正好字串 『tony』 是四個字元。

解決翻了翻文件,發現也給出了乙個佔位符查詢的例子如下

t = (』rhat』,)

c.execute(』select * from stocks where symbol=?』, t)

所以將字元引數放到元組中就可以了,修改如下:

c.execute('select * from person where p_name = ?', ('tony'))

結果依舊是丟擲了同樣的異常。再仔細看下,漏了個』,『,於是加上:

c.execute('select * from person where p_name = ?', ('tony',))

這次終於得到最終的結果了,其中的字元為 unicode 型別:

(1, u'tony')

原因但是為什麼? python 中的 sqlite3 模組提供了對 sqlite 資料操作的 api,執行查詢的函式是在 sqlite3 模組原始碼中定義的,很明顯想要知道為啥,最好的方式是去看 sqlite3 模組的原始碼。我手上的 python 原始碼是 python-2.7.4,在原始碼 python-2.7.4/modules/ sqlite/cursor.c 的函式 pyobject* pysqlite_query_execute(pysqlite_cursor self, int multiple, pyobject args) 中 497-529 行:

.../* execute() */

if (!pyarg_parsetuple(args, "o|o", &operation, &second_argument))

if (!pystring_check(operation) && !pyunicode_check(operation))

parameters_list = pylist_new(0);

if (!parameters_list)

if (second_argument == null)

} else

py_decref(second_argument);

goto error;

}py_decref(second_argument);

parameters_iter = pyobject_getiter(parameters_list);

if (!parameters_iter)

...從這段原始碼中可以看到這段**將引數 args 解析成為 python 的乙個元組作為 parameters_list ,然後最這個得到的元組進行 iter 操作,不斷地讀取這個元組的元素作為引數,而 python 中對乙個字串進行 parse tuple 會怎樣?我覺得 pyarg_parsetuple 這個函式的操作和以下**會是類似的:

...>>> tuple('test')

('t', 'e', 's', 't')

...所以現在我們可以看到我們的答案了,sqlite3 模組中,cursor 物件的 execute 方法會接受兩個引數,第二個引數會被 pyarg_parsetuple 函式轉化成為 python中 的 tuple。而對乙個字元進行 tuple parse 導致的結果是將這個字串的每個字元作為 tuple 的乙個元素,所以上面丟擲錯誤的時候提示的提供了四個所以錯誤也可以理解了。那為什麼』(『tony』)『同樣是錯誤呢?如下:

>>> type(('tony'))

>>> type(('tony',))

很明顯,(『tony』)是乙個 str 也就是乙個字串,相當於是 『tony』,而 (『tony』,) 才是乙個單元素的 tuple 。同樣,因為:

>>> tuple(['tony'])

('tony',)

所以如果那一行查詢執行改為:

c.execute('select * from person where p_name = ?', ['tony'])

同樣也是可以執行成功的。

-eof-

sqlite 模糊匹配日期 SQLite3模糊查詢

如果你還沒有安裝或者使用過 sqlite,可以借助 sqlite3 安裝 基本操作 入門。1.建立資料庫 test.db cd sqlite3 test.db 這 如果你還沒有安裝或者使用過 sqlite,可以借助 sqlite3 安裝 基本操作 入門。1.建立資料庫 test.db cd sqli...

使用sqlite3 模組操作sqlite3資料庫

python內建了sqlite3模組,可以操作流行的嵌入式資料庫sqlite3。如果看了我前面的使用 pymysql 操作mysql資料庫這篇文章就更簡單了。因為它們都遵循pep 249,所以操作方法幾乎相同。廢話就不多說了,直接看 吧。都差不多,首先匯入模組,然後建立連線,然後獲取游標物件,之後利...

python3匯入sqlite3報錯

今天把本地執行ok的scrapy爬蟲程式搗鼓到伺服器上執行,結果報了以下錯誤 2018 10 11 19 00 19 twisted critical unhandled error in deferred 2018 10 11 19 00 19 twisted critical traceback...