2013-03-20 1 views
4

그래서 저는이 python과 sqlalchemy를 처음 사용합니다. 상속이나 믹스 인 (상속)에 도움이 필요합니다.sqlalchemy의 python 상속

는 좀 psudo 코드를 가지고 있지만 난 정말 어디서나 얻을 수있는 진전되지 않은 :

Base = declarative_base() 

class ModelBase(Base): 
    """Base model that only defines last_updated""" 
    __tablename__ = 'doesnotexistandtheclassshouldnotbeinstantiated' 

    #all tables inheriting from ModelBase will have this column 
    last_updated = Column(DateTime) 

    def __init__(self, last_updated): 
    self.last_updated = last_updated 

class User(ModelBase): 
    """Defines the user but should also have the last_updated inherited from ModelBase""" 
    __tablename__ = 'user' 

    id = Column(Integer, primary_key=True) 

    def __init__(self, ....): 
    ModelBase.__init__(last_updated) 

내가 ModelBase에서 상속 모든 테이블도 LAST_UPDATED 갖고 싶어. 내가 어떻게 그럴 수 있니?

업데이트 된 코드 :

class BaseUserMixin(object): 
    """Base mixin for models using stamped data""" 

    @declared_attr 
    def last_updated(cls): 
     return Column(DateTime) 

    @declared_attr   
    def last_updated_by(cls): 
     return Column(String) 

    def __init__(self, last_updated, last_updated_by): 
     self.last_updated = last_updated 
     self.last_updated_by = last_updated_by 

Base = declarative_base(cls=BaseUserMixin) 


class User(Base): 
    __tablename__ = 'user' 

    id = Column(Integer, primary_key=True) 
    name = Column(String) 
    email = Column(String) 
    fullname = Column(String) 
    password = Column(String) 
    enabled = Column(Boolean) 

    def __init__(self, name, fullname, password, email, last_updated, last_updated_by): 
     self.name = name 
     self.fullname = fullname 
     self.password = password 
     self.email = email 
     # goes wrong here 
     super(User, self).__init__(last_updated, last_updated_by) 

    def __repr__(self): 
     return "<User('%', '%', '%', '%', '%', '%')>"\ 
       % (self.name, 
        self.fullname, 
        self.password, 
        self.email, 
        self.last_updated, 
        self.last_updated_by 
       ) 

오류 :

_declarative_constructor() takes exactly 1 argument (3 given) 

무슨 문제가 될 수있다? 나는 그것이 작동하고 있다고 생각했지만 디버거를 다시 실행할 때 실패했다.

+1

당신이이 질문에 봤습니까 cls= 인수를 사용하여 다시

from sqlalchemy import func class BaseMixin(object): @declared_attr def created_date(cls): return Column(DateTime, default=func.now()) @declared_attr def modified_date(cls): return Column(DateTime, default=func.now(), onupdate=func.now()) 

: 그건 이미 Column()에 구운거야? http://stackoverflow.com/questions/1337095/sqlalchemy-inheritance 그것은 합리적으로 좋은 답변 인 것 같습니다. – Magsol

+0

예. 것은 그들이 관련이 없다는 것이고 그것은 'polymorphic_on'이 아닙니다 ... – Asken

답변

6

용액은 declared_attr; 전화를 나타나는 DeclarativeMeta 언제든지 인스턴스에 추가 될 :

편집 : 자동적으로 super()를 호출 할 수 없습니다 declarative에서 제공하는 __init__합니다. 원한다면 마지막으로이어야하며, 그렇게 할 수있는 유일한 방법은 일반 mixin을 사용하는 것입니다. 믹스 인 처음를 제공해야

import datetime 
from sqlalchemy import Column, DateTime, Integer, String 
from sqlalchemy.ext.declarative import declared_attr, declarative_base 

class BaseMixin(object): 
    @declared_attr 
    def last_updated(cls): 
     return Column(DateTime) 

    def __init__(self, last_updated, *args, **kwargs): 
     super(BaseMixin, self).__init__(last_updated=datetime.datetime.now(), *args, **kwargs) 
     print "BaseMixin.__init__" 
     self.last_updated = last_updated 

ModelBase = declarative_base() 

주의!

class User(BaseMixin, ModelBase): 
    """Defines the user but should also have the last_updated inherited from ModelBase""" 
    __tablename__ = 'user' 

    id = Column(Integer, primary_key=True) 
    username = Column(String) 

    def __init__(self, *args, **kwargs): 
     super(User, self).__init__(last_updated=datetime.datetime.now(), *args, **kwargs) 
     print "User.__init__" 

if __name__ == '__main__': 
    from sqlalchemy import create_engine 
    from sqlalchemy.orm import sessionmaker 
    engine = create_engine('sqlite:///:memory:', echo=True) 
    ModelBase.metadata.create_all(engine) 
    user = User(username='alice') 

    Session = sessionmaker(engine) 
    session = Session() 
    session.add(user) 
    session.commit() 

그러나, 처음에 __init__을 사용 하시겠습니까? __init__은 쿼리에서 개체를 반환 할 때 호출되지 않습니다. 그리고 당신이 정말로 원하는 것은 칼럼이 변경되었을 때 바로 수정 될 것입니다. 수정되었습니다.

ModelBase = declarative_base(cls=BaseMixin) 


class User(ModelBase): 
    __tablename__ = 'user' 

    id = Column(Integer, primary_key=True) 
    username = Column(String) 

if __name__ == '__main__': 
    engine = create_engine('sqlite:///:memory:', echo=True) 
    ModelBase.metadata.create_all(engine) 
    user = User(username='alice') 

    Session = sessionmaker(engine) 
    session = Session() 
    session.add(user) 
    session.commit() 

    session = Session() 
    sameuser = session.query(User).one() 
    sameuser.username = 'bob' 
    session.commit() 
+0

"def last_updated (cls)"를 의미 했습니까? – Asken

+0

나는 약간의 독서를하지만 작동합니다 ... – Asken

+0

어쩌면 다시 볼 수 있습니까? 나는 그것이 작동하도록 할 수 없습니다. 코드 업데이트 ... – Asken