Python SQLAlchemy中的验证
我正在使用Flask和Flask SQLAlchemy extension创建一个webapp,并且在模型声明中添加了类似Python SQLAlchemy中的验证,python,sqlalchemy,Python,Sqlalchemy,我正在使用Flask和Flask SQLAlchemy extension创建一个webapp,并且在模型声明中添加了类似unique=True的字段 class Coupon(db.Model): username = db.Column(db.String(80), primary_key=True) value = db.Column(db.String(80), unique=True) is_valid = db.Column(db.Boolean)
unique=True
的字段
class Coupon(db.Model):
username = db.Column(db.String(80), primary_key=True)
value = db.Column(db.String(80), unique=True)
is_valid = db.Column(db.Boolean)
def __init__(self, value, username):
self.value = value
self.username = username
self.is_valid = True
验证失败时恢复的最佳(pythonic)方法是什么。比如说-
c1 = Coupon("same_value", "foo")
db.session.add(c1)
c2 = Coupon("same_value", "bar")
db.session.add(c2)
db.session.commit() #gives an IntegrityError
我应该用try,except块来处理这个问题吗?还是有更好的方法来处理尚未成功的转换。关于事务的一个附加查询-只要继续向会话添加对象,而不执行会话。提交是否都是一个事务的一部分
谢谢我不确定尝试catch
调用commit()
是否有意义。即使你这样做了,你如何继续?您如何进一步定位问题并解决它?您可能已经有几十个副本了
这里的格言是:及早发现错误
因此,我可能会做的是:在会话.add(c?
之后添加对会话.flush()
的调用。这将及早表明问题,以便我正确处理。因此,将add/flush
包装在try-catch
块中,并根据需要进行处理可能更有意义:
def _add_coupon(c):
""" @param c: instance of Coupon.
@return: True if success, False on failure.
"""
try:
session.add(c)
session.flush()
return True
except sqlalchemy.exc.IntegrityError as err:
# @todo: handle as appropriate: return existing instance [session.query(Coupon).filter(Coupon.value==c.value).one()] or re-raise
logger.error("Tried to add a duplicate entry for the Coupon value [%s]. Aborting", c.value)
return False
我不确定尝试catch
调用commit()
是否有意义。即使你这样做了,你如何继续?您如何进一步定位问题并解决它?您可能已经有几十个副本了
这里的格言是:及早发现错误
因此,我可能会做的是:在会话.add(c?
之后添加对会话.flush()
的调用。这将及早表明问题,以便我正确处理。因此,将add/flush
包装在try-catch
块中,并根据需要进行处理可能更有意义:
def _add_coupon(c):
""" @param c: instance of Coupon.
@return: True if success, False on failure.
"""
try:
session.add(c)
session.flush()
return True
except sqlalchemy.exc.IntegrityError as err:
# @todo: handle as appropriate: return existing instance [session.query(Coupon).filter(Coupon.value==c.value).one()] or re-raise
logger.error("Tried to add a duplicate entry for the Coupon value [%s]. Aborting", c.value)
return False
谢谢你,范。在这个方法调用之后,我确实需要执行一个db.session.commit()
,对吗?这取决于,flush()是在错误发生时立即生成错误所必需的,而不是等到调用commit。但是,如果在每次添加后调用commit(),这也应该起作用。在不知道您在这个用例/事务中所做的全部工作的情况下,很难给您一个答案。谢谢。在这个方法调用之后,我确实需要执行一个db.session.commit()
,对吗?这取决于,flush()是在错误发生时立即生成错误所必需的,而不是等到调用commit。但是,如果在每次添加后调用commit(),这也应该起作用。如果不知道您在这个用例/事务中所做的全部工作,就很难给出答案。