跳轉到內容

Karrigell/資料庫管理

來自華夏公益教科書,開放的書籍,開放的世界

資料庫引擎

[編輯 | 編輯原始碼]

Karrigell 可以使用任何資料庫引擎(MySQL、SQLite 等),使用相應的模組。在本例中,我們將使用一個非常簡單的模組來儲存我們所需的資料:對於集合中的每個 CD,藝術家名稱和專輯標題

將此複製到名為simpledb.py 

def read(filename):
    records = []
    try:
        for line in open(filename):
            records.append(line.strip().split("#"))
    except IOError:
        pass
    return records

def save(records,filename):
    out = open(filename,'w')
    for items in records:
        out.write('#'.join(items)+'\n')
    out.close()

當你在指令碼中匯入模組時,只需使用它的函式read()save(). 資訊儲存在元組列表中

對於我們的 CD 收集應用程式,資訊將僅包含 2 個值:藝術家名稱和 CD 標題。如果我們呼叫資料庫檔案mycds.db用 HTML 表格列印所有 CD 的程式碼將很簡單

simpledb = Import('simpledb')
cds = simpledb.read('mycds.db')
for (artist,title) in cds:
    print artist,title

注意你匯入模組的方式simpledb.py : 你不能使用通常的import語句,因為在像 web 伺服器這樣的共享環境中,模組名稱到檔案系統中檔案的解析存在問題。Karrigell 使用內建函式Import(module_url)用於使用者定義的模組;對於標準 Python 發行版中的模組,你可以安全地使用import

帶有 CD 列表的主頁

[編輯 | 編輯原始碼]

我們現在可以修改index()函式來列印 CD 列表

simpledb = Import('simpledb')

def index():
    print "<h1>My record collection</h1>"
    
    # login / logout
    logged = hasattr(Session(),"user") and Session().user is not None
    if logged:
        print 'Logged in as %s<br>' %Session().user
        print '<a href="logout">Logout</a><p>'
    else:
        print '<a href="login">Login</a><p>'

    # print existing records
    cds = simpledb.read('mycds.db')
    if cds:
        print '<table border="1">'
        print '<tr><th>Artist</th><th>Title</th></tr>'
        for (artist,title) in cds:
            print '<tr><td>%s</td><td>%s</td></tr>' %(artist, title)
        print '</table><p>'
    else:
        print "No CD in the collection<p>"

    # prompt logged in users to enter a new record
    if logged:
        print '<a href="new_cd">Enter new CD</a><p>'

    # page counter
    Include('../counter.py',counter_file='counter.txt')

注意simpledb在模組級別匯入,而不是在函式內部index() : 在模組級別定義的名稱在函式中可用,就像在普通的 Python 指令碼中一樣

新增新的 CD

[編輯 | 編輯原始碼]

對於登入使用者,有一個連結可以在資料庫中輸入新的 CD。此連結的 href 屬性為new_cd, 所以我們必須編寫一個函式new_cd()

此函式將列印一個表單來輸入 CD 藝術家和標題,並將資料提交到另一個函式,該函式實際上將資訊寫入資料庫,然後返回主頁

在此階段,你應該沒有問題理解下面的程式碼

def new_cd():
    print '<h1>New CD</h1>'
    print '<form action="insert_new_cd" method="post">'
    print 'Artist <input name="artist"><br>'
    print 'Title <input name="title"><br>'
    print '<input type="submit" value="Ok">'
    print '</form>'

def insert_new_cd(artist,title):
    cds = simpledb.read('mycds.db')
    cds.append((artist,title))
    simpledb.save(cds,'mycds.db')
    raise HTTP_REDIRECTION,"index"

將這些函式新增到index.ks並在資料庫中輸入幾個 CD。每次你回到主頁時,你都應該看到收藏在不斷增長

編輯記錄

[編輯 | 編輯原始碼]

登入使用者應該能夠編輯關於 CD 的資訊:在列表中,他們應該看到一個連結“編輯”,將他們傳送到一個頁面,在那裡可以編輯資訊

這要求將有關 CD 的資訊從主頁傳遞到編輯頁面。為此,我們可以將有關 CD 的資訊(藝術家 + 標題)附加到連結,例如href = edit?artist=Beatles&title=Revolver : 但資料庫引擎通常提供記錄識別符號,即標識記錄的整數

在我們的簡單資料庫中,我們可以使用列表中專案的索引作為識別符號,這樣我們就可以重寫程式碼來以這種方式列印 CD 收集

   # print existing records
   simple db = Import('simpledb')
   cds = simpledb.read('mycds.db')
   if cds:
       print '<table border="1">'
       print '<tr><th>Artist</th><th>Title</th></tr>'
       for num,(artist,title) in enumerate(cds):
           print '<tr><td>%s</td><td>%s</td>' %(artist, title)
           if logged:
               print '<td><a href="edit?num=%s">Edit</a></td>' %num
           print '</tr>'
       print '</table><p>'
   else:
       print "No CD in the collection<p>"

函式edit()將接收一個名為num. 傳遞給 Karrigell 服務中函式的所有引數都是位元組串,所以在使用此引數之前num作為列表中的索引,不要忘記將其轉換為整數

def edit(num):
    cds = simpledb.read('mycds.db')
    artist,title = cds[int(num)]
    print '<h1>New CD</h1>'
    print '<form action="update_cd" method="post">'
    print '<input name="num" type="hidden" value="%s">' %num
    print 'Artist <input name="artist" value="%s"><br>' %artist
    print 'Title <input name="title" value="%s"><br>' %title
    print '<input type="submit" value="Ok">'
    print '</form>'

def update_cd(num,artist,title):
    cds = simpledb.read('mycds.db')
    cds[int(num)] = (artist,title)
    simpledb.save(cds,'mycds.db')
    raise HTTP_REDIRECTION,"index"

刪除記錄

[編輯 | 編輯原始碼]

最後一步是啟用從基座中刪除 CD:再次編輯函式index()像這樣

   # print existing records
   simpledb = Import('simpledb')
   cds = simpledb.read('mycds.db')
   if cds:
       print '<table border="1">'
       print '<tr><th>Artist</th><th>Title</th>'
       if logged:
           print '<th> </th>'*2
       print '</tr>'
       for num,(artist,title) in enumerate(cds):
           print '<tr><td>%s</td><td>%s</td>' %(artist, title)
           if logged:
               print '<td><a href="edit?num=%s">Edit</a></td>' %num
               print '<td><a href="remove?num=%s">Remove</a></td>' %num
           print '</tr>'
       print '</table><p>'
   else:
       print "No CD in the collection<p>"

並新增一個新函式,remove():

def remove(num):
    cds = simpledb.read('mycds.db')
    del cds[int(num)]
    simpledb.save(cds,'mycds.db')
    raise HTTP_REDIRECTION,"index"

現在我們有一個完整的應用程式來管理我們的 CD 收集。指令碼 index.ks 中應用程式的結構與任何 Python 模組一樣清晰

simpledb = Import('simpledb')

def index():
    ...
    # login / logout
    ...
    # print existing records
    ...
    # prompt logged in users to enter a new record
    ...
    # page counter
    ...
def login():
    ...
def check_login(login,passwd):
    ...
def logout():
    ...
def new_cd():
    ...
def insert_new_cd(artist,title):
    ...
def edit(num):
    ...
def update_cd(num,artist,title):
    ...
def remove(num):
    ...

每個函式對應於應用程式的一個頁面。對於接收使用者輸入的頁面,欄位是函式的引數(始終是字串)

在本簡短的演示中,你看到你需要知道的只是 Python 和 HTML。該軟體包不需要任何配置,對於程式設計師來說,Karrigell 只提供了一小部分額外的內建名稱

華夏公益教科書