我正在阅读关于基本关系的SQLAlchemy文档,我觉得我缺少一些关于如何创建关系声明的基本理解。当我运行我的代码时,我遇到了错误,例如:
sqlalchemy.exc.NoForeignKeysError: Can't find any foreign key relationships between 'entity' and 'category'.
sqlalchemy.exc.NoForeignKeysError: Could not determine join condition between parent/child tables on relationship Entity.categories - there are no foreign keys linking these tables. Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or specify a 'primaryjoin' expression.
我认为relationship()指令的目的是最小化手动键和id的创建。
关于一对多和多对多,多对一以及语法如何区分不同类型的关系,我对语法也有点困惑。
这是我的例子,我在其中创建一个实体和各种类来尝试各种关系:
class Entity(Base):
__tablename__ = 'entity'
id = Column(Integer, primary_key=True)
name = Column(String(250), nullable=False )
# many-to-one - many entities will belong to one manufacturer
# do i need to define the mfg_id manually?
manufacturer_id = Column(Integer, ForeignKey('manufacturer.id'))
manufacturer = relationship("Manufacturer")
# one-to-many relationship where an entity will have lots of
# properties that belong to it. Each property will only belong to one entity
properties = relationship("EntityProperty", backref="entity")
# this is a many-to-many relationship mapping where entity can belong
# to multiple categories and you can look up entities by category
categories = relationship("Category", backref="entities")
class EntityProperty(Base):
__tablename__ = 'entity_property'
id = Column(Integer, primary_key=True)
key = Column(String(250), nullable=False )
value = Column(String(250), nullable=False )
# do we need to define this? or can this be implied by relationship?
entity_id = Column(Integer, ForeignKey('entity.id'))
class Category(Base):
__tablename__ = 'category'
id = Column(Integer, primary_key=True)
name = Column(String(250), nullable=False )
# Does this need to know anything about entities? Many entities
# can belong to a category and entities can also belong to multiple
# categories. Usage is to look up entities that belong to a category.
class Manufacturer(Base):
__tablename__ = 'manufacturer'
id = Column(Integer, primary_key=True)
name = Column(String(250), nullable=False )
# Similar to category except not all manufactures would have entities.
# How to decouple code at this level from entity
有人能指出我正确的方向,以了解关于正确使用关系()的更多信息吗?谢谢
答案 0 :(得分:1)
首先,实体表中必须有一个外键引用类别表中的列(反之亦然)以建立关系。你现在没有。 但是,如果您打算在实体和类别之间建立多对多的关系,那么请注意 SQLAlchemy many-to-many Relationships
答案 1 :(得分:0)
有时你最终会在提出问题后立即解决自己的问题。这就是我学到的东西。
我对back_populdate vs backref感到有些困惑。我想如果我添加了一个backref,我不需要在相反的类中添加外键,但这是不正确的。
所以对于一对多:
这在实体
中声明properties = relationship("EntityProperty", backref="entity")
这是在EntityProperty中声明的,以便于进行必要的反向链接,并且是必需的:
entity_id = Column(Integer, ForeignKey("entity.id"))
在多对多的情况下,我错过了一个关联表:
cat_entity_association_table = Table("cat_entity_assocaition", Base.metadata,
Column("category_id", Integer, ForeignKey("category.id")),
Column("entity_id", Integer, ForeignKey("entity.id")),
)
此关联用于构建实体之间的双向链接:
categories = relationship("Category", secondary=cat_entity_association_table, back_populates="entities")
和类别:
entities = relationship("Entity", secondary=cat_entity_association_table, back_populates="categories")
何时使用外部表格存在一些歧义,但希望这也有助于其他人。