모델이 상속하는 mixin 클래스를 만드는 대신 다른 방법으로 클래스를 구성해야하는 유스 케이스가 있습니다. 일반적으로 믹스 인 클래스가 될 클래스는 모델 객체를 생성하는 클래스뿐만 아니라 모델을 상속하는 클래스 여야합니다. 이는 모델 및 매퍼 구성이 기본 저장소의 외부 라이브러리에 있기 때문입니다. 모델을로드하기 전에 기본 저장소에서 모델 라이브러리로 엔진의 호스트를 전달하여 이미 구성된 선언적 기본을로드 할 수 있어야합니다. 엔진 정보가 전달 된 후에는 세션, 기본 클래스 및 모든 것이 모델이 상속하는 일종의 기본 클래스 내에서 만들어집니다. 다음은 간단한 예입니다 :외부 라이브러리에서 sqlalchemy 모델을 상속하는 사용자 정의 클래스를 만드는 방법
class SQLAlchemyBase(object):
metadata = None
Session = None
Base = object
sessionfactory = sessionmaker()
def initialize(self, host):
engine = create_engine(host)
self.metadata = MetaData(bind=engine)
self.Session = scoped_session(self.sessionfactory)
self.Base = declarative_base(metadata=self.metadata)
models = SQLAlchemyBase()
(모델은 models.Base에서 상속) 그래서 SQLAlchemyBase 메인 저장소로 가져옵니다
, 초기화 방법은의 호스트에 전달 호출됩니다 엔진으로 변환 한 다음 모델을 가져올 수 있습니다. 주 저장소는 모델과 동일한 이름을 가진 자체 클래스를 가지고 있으며 일반적인 mixin 클래스가 기능을 확장해야하는 추가 메소드를 가지고 있습니다. 그러나 외부 저장소 라이브러리에서 확장 된이 비정상적인 상속을 사용하여 매퍼를 훌륭하게 재생할 수 없으므로 기본 저장소의 클래스를 사용하여 모델 개체를 만들 수 없습니다. 또한 모델 라이브러리에는 여러 수준의 상속 된 다형성 관계가있는 모델이 있습니다. 내가 점점 된 원래 오류는 것이었다
class Foo(models.Base):
__tablename__ = "foo"
id = Column(Integer, primary_key=True)
type = Column(String)
foo_bar_id = Column(Integer, ForeignKey("foo_bar.id"))
foo_bar = relationship(Foo, backref=backref("foos"))
__mapper_args__ = {"polymorphic_on": type}
class Bar(Foo):
__mapper_args__ = {"polymorphic_identity": "bar"}
class FooBar(models.Base):
__tablename__ = "foo_bar"
id = Column(Integer, primary_key=True)
홈페이지 저장소
from separate_library.models import models, Foo as BaseFoo, Bar as BaseBar, FooBar as BaseFooBar
class Foo(BaseFoo):
@classmethod
def custom_create_method(cls, **kw):
foo_obj = cls(**kw)
models.session.add(foo_obj)
models.session.flush()
class Bar(BaseBar):
pass
class FooBar(BaseFooBar):
pass
모델 라이브러리 : 여기에 기본적인 상속 다형성 관계 중 하나와 유사한 예입니다 이렇게 :
InvalidRequestError
: 하나 이상의 맵퍼가 초기화하지 못했습니다. 다른 맵퍼 초기화를 진행할 수 없습니다.
원본 예외 :이 선언적베이스의 레지스트리에 경로Foo
에 대해 여러 클래스가 있습니다. 완전한 모듈 공인 경로를 사용하십시오.
그래서 관계의 전체 경로를 시도했습니다.
FlushError
: 수집FooBar.foos
의 구성원으로 유형의 항목을 플러시하려고 그런 다음 다음과 같이 나에게 오류를 제공하기 시작했다. 이 객체는, 형태의 객체 또는이 형태의 다형성 서브 클래스가 필요합니다. if의 하위 클래스 인 경우 매퍼Mapper|Foo|foo
을 구성하여이 하위 유형을 다형 적으로로드하거나enable_typechecks=False
을 설정하여 모든 하위 유형을 플러시 할 수 있도록 허용합니다.
기본적으로 주 모듈의 클래스가 모델 클래스를 가리키고 동작하도록하는 것이 주된 문제입니다. 예를 들어 관계를 만들려고 할 때 main_module.models.Foo
대신 separate_library.models.Foo
유형의 개체가 필요하다고합니다. 또한 다형성 관계에서 polymorphic_onity 열에 대한 polymorphic_identity를 채울 수 없습니다. 예를 들어, 객체가 처음 생성 될 때 주 저장소의 Bar는 type
열을 비 웁니다.
내가 시도한 한 가지 아이디어는 모델 라이브러리의 선언적 기본에 메타 클래스를 추가하고 초기화 중에 __init__
메서드에서 매퍼를 수정하는 것이 었습니다. 나는 이런 식으로 진전을 보였지만 완전히 작동하지는 못했다.
복잡한 설명을 드려 죄송합니다. 그러나 이것은 복잡한 문제입니다. 불행히도 모델이나 유스 케이스에 대해서는 아무 것도 변경할 수 없다. 이러한 제약 조건 안에서 작업해야합니다. 누구나 모델 저장소의 모델처럼 작동하도록 기본 저장소의 클래스에 대한 매퍼를 구성하는 방법에 대한 아이디어를 제공 할 수 있다면 매우 감사하게 생각합니다.