2012-06-21 2 views
1

나는 웹 응용 프로그램을 만들기 위해 Flask와 flask-SQLAlchemy 확장을 사용하고 모델 선언에 unique=True과 같은 필드를 추가했습니다.SQLAlchemy의 유효성 검사

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 

유효성 검사 실패시 복구하는 가장 좋은 방법은 무엇입니까? 예 :

c1 = Coupon("same_value", "foo") 
db.session.add(c1) 
c2 = Coupon("same_value", "bar") 
db.session.add(c2) 
db.session.commit() #gives an IntegrityError 

이 문제를 해결하기 위해 블록을 사용해야합니까? 또는 성공하지 못했던 번역을 다루는 더 좋은 방법이 있습니다. 트랜잭션에 관한 추가 쿼리 - 세션에 객체를 계속 추가하고 session.commit을 수행하지 않는 한 모든 것은 하나의 변환입니다. 이 try-catchcommit() 호출에 의미가있는 경우

덕분에

답변

4

나는 확실하지 않다. 네가하는 경우에도 어떻게 더 진행하니? 문제를 어떻게 찾아서 수정합니까? 이미 수십 개의 복제본이있을 수 있습니다.

여기서의 모토는 다음과 같습니다. 캐치 오류 미리입니다.
그러므로 내가 할 수있는 것은 session.add(c?) 바로 뒤에 session.flush()에 대한 호출을 추가하는 것입니다. 이렇게하면 문제를 조기에 적절하게 처리 할 수 ​​있습니다.

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 
+0

감사 밴 : 그래서 더 의미가 try-catch 블록에서 add/flush을 포장하고 적절하게 처리하기 위해 만들 수 있습니다. 이 메소드 호출 바로 다음에'db.session.commit()'을 할 필요가 있습니까? – Prakhar

+0

이것은 flush()가 발생하자마자 오류를 생성하고 커밋이 호출 될 때까지 기다리지 않는 데 필요한 것에 의존합니다. 그러나 추가 할 때마다 commit()을 호출하면이 작업도 가능합니다. 이 유스 케이스/트랜잭션에서 수행하는 작업의 전체 범위를 모른 채로 대답을하는 것은 어렵습니다. – van

관련 문제