2016-12-30 3 views
1

이처럼 정의 된 모델 클래스가 있습니다. 그 아이디어는 Person이 사람에 대한 일반적인 정보를 담고있을뿐만 아니라 "하위 클래스"인 여성과 남성을 부모로 언급한다는 것입니다. 여성과 남성은 해당 성별에 특정한 정보를 보유하게됩니다.자체 참조 테이블에서 모호한 외래 키 [SQLAlchemy/Alembic]

내가 마이그레이션을 생성하기 위해 증류기를 사용하고 있지만 오류가 받고 있어요 :

sqlalchemy.exc.AmbiguousForeignKeysError : 결정할 수 없습니다 것은 '사람'과 '여성'사이에 조인 테이블에는 두 개 이상의 외부 키 제한 조건 관계가 있습니다. 이 조인의 'onclause'를 명시 적으로 지정하십시오.

여성은 사람을 상속하므로 여성에서 사람에게도 참고가 있음을 유의하십시오.

  • 제거 라인 mother = relationship('Woman') 아이디어와 SQL의 연금술 mother_id = Column(Integer, ForeignKey('woman.id'), nullable=True)
  • mother = relationship('Woman', primaryjoin='Person.mother_id==Mother.id')
  • 이 onclause 지정 추가 추가 그 관계

  • 을 이해하지 않습니다 수 없습니다 :

    아무것도 나는 일을 시도하지 (또는 어떻게해야할지 모르겠다) 자동으로 생성되기 때문에

    class Person(Base): 
        __tablename__ = 'person' 
    
        id = Column(Integer, primary_key=True) 
        gender = Column(String(5)) 
        name = Column(String(32), nullable=False) 
        surname = Column(String(32), nullable=False) 
        age = Column(Float, primary_key=True) 
    
        mother_id = Column(Integer, ForeignKey('woman.id'), nullable=True) 
        mother = relationship('Woman') 
    
        _mapper_args__ = { 
         'polymorphic_on': gender 
        } 
    
    
    class Woman(Person): 
        __tablename__ = 'woman' 
        __mapper_args__ = { 
         'polymorphic_identity': 'woman' 
        } 
    
        id = Column(Integer, ForeignKey('person.id'), primary_key=True) 
    

전체 추적은 :

$ alembic revision --autogenerate -m "mother" 
Traceback (most recent call last): 
    File "/Library/Frameworks/Python.framework/Versions/3.4/bin/alembic", line 11, in <module> 
    sys.exit(main()) 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/alembic/config.py", line 479, in main 
    CommandLine(prog=prog).main(argv=argv) 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/alembic/config.py", line 473, in main 
    self.run_cmd(cfg, options) 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/alembic/config.py", line 456, in run_cmd 
    **dict((k, getattr(options, k)) for k in kwarg) 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/alembic/command.py", line 117, in revision 
    script_directory.run_env() 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/alembic/script/base.py", line 416, in run_env 
    util.load_python_file(self.dir, 'env.py') 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/alembic/util/pyfiles.py", line 93, in load_python_file 
    module = load_module_py(module_id, path) 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/alembic/util/compat.py", line 68, in load_module_py 
    module_id, path).load_module(module_id) 
    File "<frozen importlib._bootstrap>", line 539, in _check_name_wrapper 
    File "<frozen importlib._bootstrap>", line 1614, in load_module 
    File "<frozen importlib._bootstrap>", line 596, in _load_module_shim 
    File "<frozen importlib._bootstrap>", line 1220, in load 
    File "<frozen importlib._bootstrap>", line 1200, in _load_unlocked 
    File "<frozen importlib._bootstrap>", line 1129, in _exec 
    File "<frozen importlib._bootstrap>", line 1471, in exec_module 
    File "<frozen importlib._bootstrap>", line 321, in _call_with_frames_removed 
    File "migrations/env.py", line 24, in <module> 
    import api.model 
    File "/Users/jakubt/Projects/hex/api/model.py", line 31, in <module> 
    class Woman(Person): 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/sqlalchemy/ext/declarative/api.py", line 64, in __init__ 
    _as_declarative(cls, classname, cls.__dict__) 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/sqlalchemy/ext/declarative/base.py", line 88, in _as_declarative 
    _MapperConfig.setup_mapping(cls, classname, dict_) 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/sqlalchemy/ext/declarative/base.py", line 103, in setup_mapping 
    cfg_cls(cls_, classname, dict_) 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/sqlalchemy/ext/declarative/base.py", line 135, in __init__ 
    self._early_mapping() 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/sqlalchemy/ext/declarative/base.py", line 138, in _early_mapping 
    self.map() 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/sqlalchemy/ext/declarative/base.py", line 530, in map 
    **self.mapper_args 
    File "<string>", line 2, in mapper 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/sqlalchemy/orm/mapper.py", line 671, in __init__ 
    self._configure_inheritance() 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/sqlalchemy/orm/mapper.py", line 978, in _configure_inheritance 
    self.local_table) 
    File "<string>", line 2, in join_condition 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/sqlalchemy/sql/selectable.py", line 965, in _join_condition 
    a, b, constraints, consider_as_foreign_keys) 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/sqlalchemy/sql/selectable.py", line 1055, in _joincond_trim_constraints 
    "join explicitly." % (a.description, b.description)) 
sqlalchemy.exc.AmbiguousForeignKeysError: Can't determine join between 'person' and 'woman'; tables have more than one foreign key constraint relationship between them. Please specify the 'onclause' of this join explicitly. 

답변

0

내가 여기 문제로 참조하면 외래 키에 외래 키를 참조하는 것입니다.

mother_id -> foreign_key(woman.id) 
woman.id -> foreign_key(person.id) 

그리고 순환 의존성을 만듭니다. 모든 SQL 언어의 단일 작성 문에서 그 종속성을 작성할 수 없습니다. 먼저 person 테이블을 만들고 woman 테이블을 만든 다음 테이블에 foreign key (mother_id)을 추가해야합니다. 여성 테이블을 먼저 만들 수 없다는 점에 유의하십시오. 사람 테이블에 외래 키가 있습니다.

나는이 일을하기에 충분히 똑똑하다고 생각하지 않으며, 당신이 달성하기를 원하는 것이 좋지 않다고 생각합니다.

woman.id 항상 person.id로 하나 개의 레코드에 대해 동일한 값을 갖게됩니다, 그래서 첫 번째 외래 키는 사람이 테이블 대신 어머니의 표를 참조한다 : 여기

내가 제안 것입니다.

변경 mother_id의 정의와 mother :

mother_id = Column(Integer, ForeignKey('person.id'), nullable=True) 
mother = relationship('Person', primaryjoin='Person.mother_id==Person.id') 

팁 : 그냥 ID를 저장하는 경우 당신이

체크를 (단지 두 번째 클래스에서 __tablename__ 제거) 두 번째 테이블이 필요하지 않습니다 어머니/아버지 추가시 성별 코드

+0

감사합니다. 이것이 내 계획 B입니다.나 또한 순서대로 테이블을 만들려고했는데 - 처음에는 테이블 사람을 만들고 그 다음 하위 테이블 여성을 자식 테이블로 만든 다음 제한을 추가하면 작동하지 않았다. 이 예제에서는 여성 테이블을 잘라 냈습니다. 그것은 많은 열을 포함합니다. –