Python SQLAlchemy中的验证

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)

我正在使用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)

    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(),这也应该起作用。如果不知道您在这个用例/事务中所做的全部工作,就很难给出答案。