2016-12-30 38 views
1

私はこのように定義されたモデルクラスを持っています。アイデアは、Personは、人々に関する一般的な情報を保持するだけでなく、そのサブクラスである女性と男性を親として参照するということです。女性と男性はその性別に固有の情報を保持します。自己参照表のあいまいな外部キー[SQLAlchemy/Alembic]

私は、マイグレーションを発生させるためにアレンビックを使用していますが、私はエラーを取得しています:

sqlalchemy.exc.AmbiguousForeignKeysErrorを「人」と「女性」の間に参加を決定することはできません。表に複数の外部キー制約関係があります。この結合の 'onclause'を明示的に指定してください。

女性はPersonから継承されるため、女性から人への参照もあります。私は作品を試してみました

ナッシング:SQLの錬金術は、その関係に

  • を理解していないonclause指定mother = relationship('Woman', primaryjoin='Person.mother_id==Mother.id')
  • を追加mother_id = Column(Integer, ForeignKey('woman.id'), nullable=True)

  • を追加することができないという考えに

    • 削除ラインmother = relationship('Woman')結合が自動生成されているため(またはわからない)

      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ように、1つのレコードに対して同じ値を持つことになりますので、最初の外部キーではなく、母のテーブルの人のテーブルに参照する必要があります。

    変更mother_idの定義とmother

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

    ヒント:あなただけのIDを格納している場合は、

    とチェックを(ちょうど第二のクラスから__tablename__を削除する)は、第2のテーブルを必要としません。母親/父親を追加するときのジェンダーのコード。

    +0

    ありがとう、これは私の計画Bです。私も順番にテーブルを作成しようとしました - 最初にテーブルの人を作成し、次にサブテーブルの女性を子テーブルとして作成し、制約を追加すると、それも機能しませんでした。 私はこの例の女性テーブルを切り捨てました。それは多くの列を含んでいます。 –

    関連する問題