跳转到内容

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 只提供了一小部分额外的内置名称

华夏公益教科书