sqlalchemy 与父类的外键关系

Nic*_*ick 2 python database sqlalchemy foreign-keys hierarchy

我有以下数据库架构:

父表:

  1. id - 主键标识符。
  2. 类型 - 多态身份。
  3. 名称 - 字符串数据列。

子表 - 继承父表:

  1. id - 主键标识符。
  2. Parent_id - 父级的外键。
  3. 类别 - 字符串数据列。

总结一下,我有两张桌子。Child 表继承自 Parent 并且也有一个外键。

UPD:我真的需要继承和外键。此示例只是一个重现问题的简短演示。

我使用 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)
Run Code Online (Sandbox Code Playgroud)

但是当我运行代码时,出现以下错误:

sqlalchemy.exc.AmbigouslyForeignKeysError:无法确定“父级”和“子级”之间的连接;表之间有多个外键约束关系。请明确指定此连接的“onclause”。

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

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

Nic*_*ick 5

我在这里找到了解决方案。

在这种情况下,SQLAlchemy 需要提示:Child 的__mapper_args__中的继承条件字段可以解决问题。

# -*- 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)
Run Code Online (Sandbox Code Playgroud)