2013-05-01 30 views
0

如果我有我的models/db.py是这样的:如何在web2py的数据库级别创建多列唯一约束?

db.define_table('magazine', Field('name'), Field('description')) 
    db.define_table('subscribe', Field('subscriber', db.auth_user), Field('magazine', db.magazine)) 

而且在controller/default.py

# subscribe callback from view 
@auth.requires_login() 
def subscribe(): 
    mag_id = request.args(0, cast=int) 
    db.subscribe.insert(magazine=mag_id, subscriber=auth.user.id) 

用户会点击订阅按钮,应该调用回调并插入用户进入订阅他正在查看当前杂志的表格。

我该如何让订阅表包含订阅者和杂志的独特组合?已订阅杂志的订阅者不应再次订阅同一杂志。

例如,这应该工作:

用户1,杂志1
用户1,杂志2
用户2杂志1

但是,这不应该:

用户1 ,杂志1
用户1,杂志1

一个解决方案是手动检查combinat离子已经存在我的控制器内:

def subscribe(): 
    mag_id = request.args(0, cast=int) 
    subscribed = db(db.subscribe.subscriber==auth.user.id)&(db.subscribe.magazine==mag_id)) 

    if len(subscribed) < 1: 
     # Do insert 
    else: 
     # Do nothing, user is already subscribed. 

但是,有没有更好的方式(最好是在数据库级别)来做到这一点?我看过使用IS_NOT_IN_DB()可以工作,但似乎只限于使用表单? This thread也表明它不起作用。

回答

0

DAL没有提供在数据库中指定多列唯一性约束的方法,但您可以直接在web2py以外的数据库中执行此操作。但是,您可能仍然希望应用程序中有一些明确的代码来处理此问题 - 否则数据库级别的违规将最终生成异常。在这种情况下,你可以简单地使用.update_or_insert()方法:

db.subscribe.update_or_insert(magazine=mag_id, subscriber=auth.user.id) 

那样只会让插入如果与该杂志和用户的记录不存在。

+0

哦,这非常方便。谢谢,这可能会诀窍。 – Bak 2013-05-01 15:35:42