与父类

时间:2017-09-21 15:12:42

标签: python database sqlalchemy foreign-keys hierarchy

我有以下数据库架构:

父表

  1. id - 主键标识符。
  2. type - polymorphic_identity。
  3. name - 字符串数据列。
  4. 子表 - 继承父级:

    1. id - 主键标识符。
    2. parent_id - 来自Parent的外键。
    3. category - 字符串数据列。
    4. 总结我有两张桌子。表Child从Parent继承,并且还有一个外键。

      UPD:我真的需要继承 foreignkey 。这个例子只是一个重现问题的简短演示。

      我使用declarative_base来声明架构:

      # -*- coding: utf-8 -*-
      
      from sqlalchemy import Column, String, Integer, ForeignKey
      from sqlalchemy.orm import relationship
      from sqlalchemy.ext.declarative import declarative_base
      from sqlalchemy import create_engine
      from sqlalchemy.orm import sessionmaker
      
      Base = declarative_base()
      
      class Parent(Base):
        __tablename__ = "Parent"
        id = Column(Integer, primary_key=True)
        type = Column(String(250))
      
        name = Column(String(250))
      
        __mapper_args__ = {
          'polymorphic_identity':'Parent',
          'polymorphic_on':type
        }
      
      class Child(Parent):
        __tablename__ = 'Child'
        id = Column(Integer, ForeignKey('Parent.id'), primary_key=True)
      
        parent_id = Column(ForeignKey("Parent.id"), nullable=True)
        category = Column(String(250))
      
        __mapper_args__ = {
          'polymorphic_identity':'Child',
        }
      
      engine = create_engine('postgresql+psycopg2://joe:joe@localhost/alch')
      
      session = sessionmaker()
      session.configure(bind=engine)
      Base.metadata.create_all(engine)
      

      但是当我运行代码时,我收到以下错误:

        
          

      sqlalchemy.exc.AmbiguousForeignKeysError:无法确定'Parent'和'Child'之间的连接;表之间有多个外键约束关系。请明确指定此联接的“onclause”。

        

      我试图单独为父母或儿童设置关系属性,也为两者设置。试图使用primaryjoin和foreign_keys参数的关系。但错误是一样的。

      我对这个错误感到很困惑。 我需要帮助。

2 个答案:

答案 0 :(得分:1)

您是否尝试删除子ID字段的外键?

id = Column(Integer, ForeignKey('Parent.id'), primary_key=True)
parent_id = Column(ForeignKey("Parent.id"), nullable=True)

你需要这样的东西:

id = Column(Integer, auto_increment=True, primary_key=True)
parent_id = Column(ForeignKey("Parent.id"), nullable=True)

答案 1 :(得分:1)

我找到了解决方案here

SQLAlchemy在这种情况下需要提示:Child的 __ mapper_args __ 中的 inherit_condition 字段可以解决问题。

# -*- coding: utf-8 -*-

from sqlalchemy import Column, String, Integer, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

Base = declarative_base()

class Parent(Base):
  __tablename__ = "Parent"
  id = Column(Integer, primary_key=True)
  type = Column(String(250))

  name = Column(String(250))

  __mapper_args__ = {
    'polymorphic_identity':'Parent',
    'polymorphic_on':type
  }

class Child(Parent):
  __tablename__ = 'Child'
  id = Column(Integer, ForeignKey('Parent.id'), primary_key=True)

  parent_id = Column(ForeignKey("Parent.id"), nullable=True)
  category = Column(String(250))

  parent = relationship(Parent, foreign_keys=[parent_id])

  __mapper_args__ = {
    'polymorphic_identity':'Child',
    'inherit_condition': id == Parent.id, 
  }

engine = create_engine('postgresql+psycopg2://joe:joe@localhost/alch')

session = sessionmaker()
session.configure(bind=engine)
Base.metadata.create_all(engine)