2012-11-18 3 views
6

를 호출 할 때의 새를 객체를 기존의 대신 만들어 반환 :SQLAlchemy의 :이 같은 방법으로 SQLAlchemy의를 사용하려면 생성자

email1 = EmailModel(email="[email protected]", account=AccountModel(name="username")) 
email2 = EmailModel(email="[email protected]", account=AccountModel(name="username")) 

보통 SQLAlchemy의 계정에 대한 두 개의 항목을 작성하고 각 이메일 주소를 링크 이. 계정 이름을 고유 한 것으로 설정하면 sqlalchemy는 동일한 값을 가진 항목이 이미 있음을 알려주는 예외를 throw합니다. 이것은 모든 것을 이해하고 예상대로 작동합니다.

지금 내가 언급 코드를 허용하고 바로 AccountModel 클래스의하여 새로운 생성자를 덮어 쓰기 만 한 번 계정을 만들어 내 자신에 의한 방법을 알아 냈 : 이것은 완벽하게 작동하고

def __new__(*cls, **kw): 
    if len(kw) and "name" in kw: 
     x = session.query(cls.__class__).filter(cls[0].name==kw["name"]).first() 
     if x: return x 
    return object.__new__(*cls, **kw) 

나를. 하지만 질문은 :

  • 올바른 방법입니까?
  • 동일한 결과를 얻으려면 SQL을 사용할 수 있습니까?

나는 최신 0.8.x SQLAlchemy의 버전 및 파이썬 2.7.x 도움 :

답변

6

http://www.sqlalchemy.org/trac/wiki/UsageRecipes/UniqueObject에서 위키에 정확히 예를 들어이 같은 기능 createOrGetAccountModel를 작성하는 것이 좋습니다 것입니다.

암시보다 낫다 명시 적으로 비록 최근에 나는, 생성자를 재정의하는 대신이에 대한 @classmethod을 사용하는 것이 바람직했습니다, 또한 간단 :

user.email = Email.as_unique('[email protected]') 

(I 실제로 업데이트거야 위키가 이제 사용 옵션을 더 완벽하게 나타냄)

+0

Oukay, 정확히 내가 찾고있는 것이죠! –

1

나는 그것이를 작성하기는 이것을 달성하는 가장 좋은 방법은 아니다 생각에 대한

감사를 사용하고 있습니다 또한 생성자의 전역 변수 session에 대한 종속성과 예상치 못한 방식으로 생성자의 비헤이비어를 수정합니다. new 개체를 반환 할 것으로 예상됩니다. 예를 들어 누군가 두 개의 세션이있는 클래스를 병렬로 사용하면 코드가 실패하고 오류를 찾기 위해 코드를 파헤쳐 야합니다.

나는이 달성의 "SQLAlchemy의"방법을 알고 모르겠지만,

def createOrGetAccountModel(**kw): 
    if len(kw) and "name" in kw: 
     x = session.query(AccountModel).filter_by(name=kw["name"]).first() 
     if x: return x 
    return AccountModel(**kw) 
+0

오른쪽! 코드 유지 관리와 관련하여 완벽한 솔루션이 아닙니다. 그러나 __new__는 객체 생성을 조작하기에 완벽한 장소가 아닙니까? –

+0

예,하지만 (항상) 새로운 객체를 생성하는 것은 아니므로'__new__'는 오해의 소지가 있습니다. 'x = SomeClass()'라고 쓰면, 모든 사람들이'x'가 새로운 객체라고 기대할 것입니다 ... – MartinStettner

관련 문제