web2py中的复合键

问题描述 投票:2回答:2

我有一个在web2py中定义的表

db.define_table(
'pairing',
Field('user',writable=True,readable=True),
Field('uid', writable=True , readable=True)
)

此表需要具有唯一的用户和uid组合。 我查看了web2py文档,但没有直接的方法来定义组合键。 我们如何在web2py中定义复合方式

python web2py composite-key
2个回答
9
投票

这取决于你想要做什么。 默认情况下,web2py会自动创建一个自动递增的id字段作为每个表的主键,这是建议的方法。 如果你正在处理与复合主键旧的数据库,并且不能更改架构,你可以指定一个primarykey属性,虽然有一些限制(如解释在这里 ):

db.define_table('pairing', 
    Field('user', writable=True, readable=True), 
    Field('uid', writable=True, readable=True),
    primarykey=['user', 'uid'])

也许您真的不需要真正的复合主键,但您只需要一些方法来确保只在表中插入唯一的用户/ uid值对。 在这种情况下,您可以通过为两个字段之一指定正确构造的IS_NOT_IN_DB验证器来完成此操作:

db.define_table('pairing',
    Field('user', writable=True, readable=True),
    Field('uid', writable=True, readable=True))

db.pairing.uid.requires=IS_NOT_IN_DB(db(db.pairing.user==request.vars.user),
    'pairing.uid')

这将确保uiduser匹配插入的user的新值的记录集中是唯一的(因此useruid的组合必须是唯一的)。 注意,验证器(例如IS_NOT_IN_DB)仅在通过SQLFORM或使用SQLFORM .validate_and_insert()方法插入值时应用,因此上述内容不适用于表中的任意插入,但主要用于用户输入提交。

您还可以使用SQL在表上设置多列唯一约束(您可以直接在数据库中或通过web2py .executesql()方法执行此操作)。 但是,即使有这样的约束,您仍然希望在应用程序中进行一些输入验证,以避免数据库出错。


3
投票

我一直在使用计算字段来创建/模拟复合键。 以上述问题为例,可以按如下方式定义联结表:

from md5 import md5
db.define_table( 'pairing',
                 Field('user', writable=True, readable=True),
                 Field('uid', writable=True, readable=True),
                 Field( 'user_uid_md5', 
                        length=32,
                        unique=True,
                        writable=False,
                        readable=False,
                        compute=lambda row: md5("{0}:{1}".format(row.user,row.uid)).hexdigest()))

user_uid_md5字段在插入和更新时自动计算。 此字段的值是从两个字段useruid获取的字符串的md5哈希值。 该字段也标记为unique 。 所以数据库在这里强制执行唯一性,这适用于Anthony指出的限制。 这也应该可以模拟具有两个以上字段的复合键。 如果你看到这种方法有任何漏洞,请告诉我。

编辑:稍微更新到计算md5哈希的方式,以解释陈列维在下面的评论中指出的案例。

© www.soinside.com 2019 - 2024. All rights reserved.