Python 基于Weppy/pyDal中的另一列限制数据库插入的最佳方法?
如果同一用户已经有一个具有相同名称的项,我想限制特定表的DB插入Python 基于Weppy/pyDal中的另一列限制数据库插入的最佳方法?,python,pydal,weppy,Python,Pydal,Weppy,如果同一用户已经有一个具有相同名称的项,我想限制特定表的DB插入 Table _____________ user | place | label | -------------------------------------------------------------------------- me | san francisco | work | you | san francisco | leisure | # Thi
Table
_____________
user | place | label |
--------------------------------------------------------------------------
me | san francisco | work |
you | san francisco | leisure | # This is ok because different user
me | san francisco | leisure | # THIS IS NOT ALLOWED - INSERT FAIL
标签对于用户来说是唯一的,所以我不希望“name”列被强制为唯一的->许多用户应该能够添加相同的位置,但是标签列中有他们想要的任何“标签”
注意:使用-我没有足够的声誉来创建新标签。
一旦我能/有一个weppy标签,我就给这个问题贴上标签
我找到了一个似乎太多代码的解决方法。需要使用Place()。添加_new()
而不是内置pyDal方法:
from weppy.dal import Model, Field, belongs_to
class Place(Model):
belongs_to('user')
name = Field() # not using `unique=True` here so others can insert same names.
label = Field()
def add_new(self, user_id, name, label):
user_places = self.db(self.db.Place.user == user_id).select()
current_names = [x.name for x in user_places]
if name not in current_names:
self.create(
user=user_id,
name=name,
label=label
)
唯一性的复杂之处在于,您无法确定在web应用程序这样的并发环境中,仅使用应用程序代码是否会尊重它
例如,如果同一个用户将产生两个并发请求(在这种情况下可能不太可能,但您应该知道这一点),那么应用程序代码可能会失败,因为可以在检查和其他插入之间插入具有相同值的记录
这就是为什么您应该首先依赖数据库本身,而且由于weppy 0.7,您可以使用数据库:
请记住在添加索引后生成迁移
一旦有了具有唯一约束的索引,就可以将新记录的创建包装在try
-块中,除了
块:
try:
rv = Place.create(**some_params)
except:
# handle the error eg:
from weppy import abort
abort(422)
当然,您仍然可以在插入之前进行一些应用程序检查,但由于您需要检查多个值,并且自定义验证器只支持一个值(除非使用会话检查用户),因此您最好使用:
从文件中可以看出:
所有回调方法都应返回None或False(在python中不返回任何内容与不返回任何内容相同),否则返回True将中止当前操作
唯一性的复杂之处在于,您无法确定在web应用程序这样的并发环境中,仅使用应用程序代码是否会尊重它
例如,如果同一个用户将产生两个并发请求(在这种情况下可能不太可能,但您应该知道这一点),那么应用程序代码可能会失败,因为可以在检查和其他插入之间插入具有相同值的记录
这就是为什么您应该首先依赖数据库本身,而且由于weppy 0.7,您可以使用数据库:
请记住在添加索引后生成迁移
一旦有了具有唯一约束的索引,就可以将新记录的创建包装在try
-块中,除了
块:
try:
rv = Place.create(**some_params)
except:
# handle the error eg:
from weppy import abort
abort(422)
当然,您仍然可以在插入之前进行一些应用程序检查,但由于您需要检查多个值,并且自定义验证器只支持一个值(除非使用会话检查用户),因此您最好使用:
从文件中可以看出:
所有回调方法都应返回None或False(在python中不返回任何内容与不返回任何内容相同),否则返回True将中止当前操作
我甚至没有考虑并发请求——这一点很好。谢谢。我甚至没有考虑并发请求——很好。谢谢
from weppy.dal import before_insert
class Place(Model):
@before_insert
def check_name_uniqueness(self, input_fields):
if self.db(
(self.user == input_fields['user']) &
(self.name == input_fields['name'])
).count() > 0:
return True
return False