2012-12-29 74 views
2

我正在研究一個與簡單的sqlite數據庫交互的Python程序。我試圖構建一個搜索工具,根據用戶輸入,它將交互式地「過濾」數據庫,然後返回與搜索匹配的行(項目)。例如...過濾sqlite - 逐個執行動作

我的Python程序(通過if語句,cgi.FieldStorage()和whatnot)應該能夠接受用戶輸入,然後通過數據庫搜索。這裏是該程序的通用代碼:

import cgitb; cgitb.enable() 
import cgi 
import sys 
import sqlite3 as lite 
import sys 

con = lite.connect('bikes.db') 
form = cgi.FieldStorage() 
terrain_get = form.getlist("terrain") 
terrains = ",".join(terrain_get) 

handlebar_get = form.getlist("handlebar") 
handlebars = ",".join(handlebar_get) 

kickstand = form['kickstand'].value 

正如你所看到的,那部分是接收用戶的輸入;工作正常(我認爲)。接下來,我需要幫助:

if 'dirtrocky' not in terrains: 
    FILTER the database to not return items that have "dirtrocky' in their terrain field 

然後在以後的程序,我希望能夠在我的過濾器擴展:

if 'drop' not in handlebars: 
    FILTER the database to, much like in previous one, not return items that have 'drop' in their 'handlebar' field 

我的問題是,如何才能篩選數據庫?理想情況下,我的最終結果應該是在「過濾掉」上述內容後留下的行的ID元組。

謝謝!

+0

你可以顯示你想要的數據庫模式嗎?你想如何存儲像地形這樣的多值字段? – mvp

+0

我明白你的意思了。我想我會只使用多個表。但是,在查看[這個問題](http://stackoverflow.com/questions/11535685/multiple-elements-in-one-database-cell)等答案,我有點不清楚如何人們會設置它。我理解一個*主表*的想法,其中包括ID,標題,價格等。但是,對於多值字段,您如何設置?謝謝! – tehsockz

回答

2

首先,你應該定義你的數據庫模式。最常見的方法是創建完全規範化的數據庫,是這樣的:

CREATE TABLE bikes (
    bike_id INTEGER AUTOINCREMENT PRIMARY KEY, 
    manufacturer VARCHAR(20), 
    price FLOAT, 
    ... 
); 

CREATE TABLE terrains (
    terrain_id INTEGER AUTOINCREMENT PRIMARY KEY, 
    terrain VARCHAR(20), 
    ... 
); 

CREATE TABLE handlebars (
    handlebar_id INTEGER AUTOINCREMENT PRIMARY KEY, 
    handlebar VARCHAR(20), 
    ... 
); 

CREATE TABLE bike_terrain (
    bike_id INTEGER, 
    terrain_id INTEGER 
); 

CREATE TABLE bike_handlebar (
    bike_id INTEGER, 
    handlebar_id INTEGER 
); 

注意bikes表不包含關於地形類型或車把東西:此信息將被存儲在連接表像bike_terrain

這個完全標準化的數據庫使填充有點繁瑣,但另一方面,它使查詢更容易。

你如何查詢它的多值字段?

您將需要動態構造SQL語句,像這樣:

SELECT 
    b.manufacturer, 
    b.price 
FROM bikes b, 
    terrains t, 
    bike_terrain bt 
WHERE b.bike_id = bt.bike_id 
    AND t.terrain_id = bt.terrain_id  
    AND t.terrain IN ('mountain', 'dirt', ...) -- this will be built dynamically 
    ... -- add more for handlebars, etc... 

幾乎整個WHERE子句將不得不建立和動態添加,通過動態構建SQL語句。

我強烈建議獲得一些很好的SQLite GUI來解決這個問題。在Windows上,SQLite Expert Personal非常棒,在Linux上sqliteman非常棒。

一旦你得到你的數據庫填充,它有超過幾百行的東西,你應該添加適當的索引,因此它的工作速度很快。祝你好運!

+0

太棒了!非常感謝。我現在就去睡覺,希望能夠徹底復活,並準備工作一些魔法。或者,你知道,編程。沒有真正的區別。我也會查看'sqliteman'。 – tehsockz

+0

我已經開始輸入數據庫。我有點好奇,至於如何將用戶輸入的數據添加到SQL語句中。有沒有辦法「分開」,以便我可以插入各種變量?或者,我必須通過結合各種變量/字符串來完成,然後將它們全部作爲一個大查詢發送(即a =「AND」; b = a +選擇器等) – tehsockz

+0

這是我通常所做的 - 仔細構建SQL語句。注意清理用於創建此類SQL的數據或使用'?'準備的語句以避免SQL注入。在python或perl中,您可以爲準備好的語句構建動態數組參數以實現此目的 – mvp