简体   繁体   English

sqlalchemy与父类的外键关系

[英]sqlalchemy foreignkey relation with parent class

I have the following database schema: 我有以下数据库架构:

Parent table : 父表

  1. id - primary key identifier. id-主键标识符。
  2. type - polymorphic_identity. 类型-polymorphic_identity。
  3. name - string data column. 名称-字符串数据列。

Child table - inherits Parent: 子表 -继承父

  1. id - primary key identifier. id-主键标识符。
  2. parent_id - foreignkey to Parent. parent_id-父级的外键。
  3. category - string data column. category-字符串数据列。

Summing up I have two tables. 总结一下,我有两个桌子。 Table Child inherits from Parent and also have a foreignkey to it. Table Child继承自Parent,并且也有一个外键。

UPD: I really need both inheritance and foreignkey . UPD:我真的既需要继承又需要Foreignkey This example is only a short demo which reproduces the problem. 这个例子只是一个简短的演示,它再现了问题。

I used declarative_base to declare the schema: 我用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)

But when I run the code I get the following error: 但是,当我运行代码时,出现以下错误:

sqlalchemy.exc.AmbiguousForeignKeysError: Can't determine join between 'Parent' and 'Child'; sqlalchemy.exc.AmbiguousForeignKeysError:无法确定“父母”和“孩子”之间的联接; tables have more than one foreign key constraint relationship between them. 表之间有多个外键约束关系。 Please specify the 'onclause' of this join explicitly. 请明确指定此联接的“ onclause”。

I have tried to set relationship attribute myself for Parent or for Child separately and for both too. 我尝试分别为父级或子级以及为这两者设置关系属性。 Tried to use primaryjoin and foreign_keys parameters of relationship. 试图使用primaryjoin和foreign_keys参数的关系。 But the error was the same. 但是错误是相同的。

I'm totally confused about this error. 我对此错误完全感到困惑。 I need help. 我需要帮助。

Have you tried removing the Foreign Key for the Child id field? 您是否尝试过删除“儿童ID”字段的外键?

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

You need something like this: 您需要这样的东西:

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

I found the solution here . 我在这里找到了解决方案。

SQLAlchemy needs a hint in this situation: a inherit_condition field in Child's __mapper_args__ does the trick. 在这种情况下,SQLAlchemy需要一个提示:Child的__mapper_args__中的native_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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM