未强制执行 web2py 唯一约束
web2py unique constraint not being enforced
我是 web2py 的新手。我正在申请文件登记。每份文件都分配了一个编号,在注册年份是唯一的。我试图有一个计算字符串字段,结合数字和年份,强制执行 unique=True
约束。
我正在使用 SQLite,web2py 默认数据库。我的 table 定义:
db.define_table('doc_master_new',
Field('sr_no', 'string', unique=True, notnull=True,
compute=lambda r: str(r['inward_no']) + '/' + str(r['inward_date'].year)),
Field('inward_no', 'integer'),
Field('inward_date', 'date', default=request.now),
Field('doc_date', 'date'),
Field('doc_type', db.doc_type, requires=IS_IN_DB(db, db.doc_type, '%(type_code)s', orderby=db.doc_type.id)),
Field('applicant_type'), ## creditor/borrower/third-party
Field('no_defect', 'boolean', default=False),
Field('time_stamp', 'datetime', default=request.now)
)
和控制器:
def add_doc():
db.doc_master_new.sr_no.writable = False
db.doc_master_new.sr_no.readable = False
db.doc_master_new.time_stamp.writable = False
db.doc_master_new.time_stamp.readable = False
db.doc_master_new.no_defect.writable = False
db.doc_master_new.no_defect.readable = False
form = SQLFORM(db.doc_master_new,
labels = { 'inward_no':'SR No',
'inward_date':'SR Date',
'doc_date':'Document Date',
'doc_type':'Document Type',
}
)
if form.process().accepted:
session.flash = 'Document Added'
redirect(URL('index_n'))
return locals()
未强制执行唯一约束,并且正在向 table 中插入相同的值。我不明白为什么。 SQLite 文档说 NULL 值被认为与所有其他值不同,包括其他 NULL,因此添加了 notnull
约束,但仍然允许重复。
有人可以帮忙吗?
您很可能在 table 最初创建 table 之后添加了 unique=True
。尽管他们的 DAL 处理迁移,但它不会更改 UNIQUE
和 NOT NULL
等约束——如果你想在 table 已经创建后更改这些约束,你必须做一些通过其他工具。
此外,请记住 unique=True
是在数据库级别强制执行的,而不是表单输入级别。这意味着如果用户提交了违反约束的值,数据库驱动程序将抛出异常并且用户将看到错误单。相反,考虑在提交表单时强制执行约束,可能通过 .process()
的 onvalidation
callback。这样,您可以防止重复的组合被发送到数据库并向用户报告友好的错误消息。
最后,如果 sr_no
字段的唯一目的是强制执行唯一性约束,请考虑设置多列唯一性约束(您必须在 DAL 之外执行此操作,它确实不提供定义此类约束的机制)。
我是 web2py 的新手。我正在申请文件登记。每份文件都分配了一个编号,在注册年份是唯一的。我试图有一个计算字符串字段,结合数字和年份,强制执行 unique=True
约束。
我正在使用 SQLite,web2py 默认数据库。我的 table 定义:
db.define_table('doc_master_new',
Field('sr_no', 'string', unique=True, notnull=True,
compute=lambda r: str(r['inward_no']) + '/' + str(r['inward_date'].year)),
Field('inward_no', 'integer'),
Field('inward_date', 'date', default=request.now),
Field('doc_date', 'date'),
Field('doc_type', db.doc_type, requires=IS_IN_DB(db, db.doc_type, '%(type_code)s', orderby=db.doc_type.id)),
Field('applicant_type'), ## creditor/borrower/third-party
Field('no_defect', 'boolean', default=False),
Field('time_stamp', 'datetime', default=request.now)
)
和控制器:
def add_doc():
db.doc_master_new.sr_no.writable = False
db.doc_master_new.sr_no.readable = False
db.doc_master_new.time_stamp.writable = False
db.doc_master_new.time_stamp.readable = False
db.doc_master_new.no_defect.writable = False
db.doc_master_new.no_defect.readable = False
form = SQLFORM(db.doc_master_new,
labels = { 'inward_no':'SR No',
'inward_date':'SR Date',
'doc_date':'Document Date',
'doc_type':'Document Type',
}
)
if form.process().accepted:
session.flash = 'Document Added'
redirect(URL('index_n'))
return locals()
未强制执行唯一约束,并且正在向 table 中插入相同的值。我不明白为什么。 SQLite 文档说 NULL 值被认为与所有其他值不同,包括其他 NULL,因此添加了 notnull
约束,但仍然允许重复。
有人可以帮忙吗?
您很可能在 table 最初创建 table 之后添加了 unique=True
。尽管他们的 DAL 处理迁移,但它不会更改 UNIQUE
和 NOT NULL
等约束——如果你想在 table 已经创建后更改这些约束,你必须做一些通过其他工具。
此外,请记住 unique=True
是在数据库级别强制执行的,而不是表单输入级别。这意味着如果用户提交了违反约束的值,数据库驱动程序将抛出异常并且用户将看到错误单。相反,考虑在提交表单时强制执行约束,可能通过 .process()
的 onvalidation
callback。这样,您可以防止重复的组合被发送到数据库并向用户报告友好的错误消息。
最后,如果 sr_no
字段的唯一目的是强制执行唯一性约束,请考虑设置多列唯一性约束(您必须在 DAL 之外执行此操作,它确实不提供定义此类约束的机制)。