可以属于几种可能模型之一的 SQLAlchemy 外键?

SQLAlchemy Foreign Key that can belong to one of several possible Models?

我有一个模型 Animals,其中字段 locationID 是一个外键,可以是 Forests.idZoos.id。假设 Forests.idZoos.id 永远不相同。

问题:这在SqlAlchemy中可以完成吗?

Base = declarative_base()

class Forests(Base):
    __tablename__       = 'forests'
    id                  = Column(String(16), primary_key=True)

class Zoos(Base):
    __tablename__       = 'zoos'
    id                  = Column(String(16), primary_key=True)

class Animals(Base):
    __tablename__       = 'animals'
    name                = Column(String(16), primary_key=True)
    locationID          = Column(String(16), ForeignKey(Forests.id or Zoos.id)) # something like this...

更多详情

在 Sqlalchemy 文档的示例中找到类似的内容,例如

class Employee(Base):
    __tablename__ = 'employee'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    type = Column(String(50))

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

class Engineer(Employee):
    __tablename__ = 'engineer'
    id = Column(Integer, ForeignKey('employee.id'), primary_key=True)
    engineer_name = Column(String(30))

    __mapper_args__ = {
        'polymorphic_identity':'engineer',
    }

class Manager(Employee):
    __tablename__ = 'manager'
    id = Column(Integer, ForeignKey('employee.id'), primary_key=True)
    manager_name = Column(String(30))

    __mapper_args__ = {
        'polymorphic_identity':'manager',
    }

EngineerManageremployee table

中都有外键

然而,我需要的是 Employeeengineermanager table 中具有外键,类似于下面的代码。

下面的代码只是为了说明目的,它显然不会工作

class Employee(Base):
    __tablename__ = 'employee'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    type = Column(String(50), ForeignKey('Engineer.id') or ForeignKey('Manager.id'))

class Engineer(Employee):
    __tablename__ = 'engineer'
    id = Column(Integer, primary_key=True)
    engineer_name = Column(String(30))

class Manager(Employee):
    __tablename__ = 'manager'
    id = Column(Integer, primary_key=True)
    manager_name = Column(String(30))

在这种情况下,也许我们需要更多地研究我们的模型,一个很好的开始问题可能是:

Do zoos and forests have something in common?

  • 那里住着动物
  • GPS 坐标
  • 人类用来称呼他们的名字

Are there differences between them?

  • 动物园通常有入场费
  • 动物园有围栏
  • 森林有一个 type,可能对我们的动物居民很重要

从上面我们可以得出结论,森林和动物园有一个共同的基础,因为如果我们将它们分解为基础,它们对于我们的目的是相同的,例如他们是我们 Animal.

Dwelling

基于文档中的示例,我们可以这样定义它:

class Dwelling(Base):
    __tablename__ = 'dwelling'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    type = Column(String(50))

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

class Forest(Dwelling):
    __tablename__ = 'forest'
    id = Column(Integer, ForeignKey('dwelling.id'), primary_key=True)
    biome = Column(String(30))

    __mapper_args__ = {
        'polymorphic_identity':'forest',
    }

class Zoo(Dwelling):
    __tablename__ = 'zoo'
    id = Column(Integer, ForeignKey('dwelling.id'), primary_key=True)
    fee = Column(Integer)

    __mapper_args__ = {
        'polymorphic_identity':'zoo',
    }

对于我们的 Animal,它看起来像这样:

class Animal(Base):
    __tablename__ = 'animal'
    name = Column(String(16), primary_key=True)
    location = Column(Integer, ForeignKey(Dwelling.id))

希望对您有所帮助。