Python SQLAlchemy如何与backrefs建立各种关系?

Python SQLAlchemy如何与backrefs建立各种关系?,python,sqlalchemy,Python,Sqlalchemy,我正在阅读有关基本关系的SQLAlchemy文档,我觉得我缺少了一些关于如何创建关系声明的基本理解。当我运行代码时,我会遇到以下错误: sqlalchemy.exc.NoForeignKeysError: Can't find any foreign key relationships between 'entity' and 'category'. sqlalchemy.exc.NoForeignKeysError: Could not determine join condition be

我正在阅读有关基本关系的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

有人能给我指出正确的方向,让我进一步了解relationship()的正确用法吗?谢谢

首先,实体表中必须有一个外键引用类别表中的列(反之亦然),才能建立关系。你目前没有。 然而,如果您打算在实体和类别之间建立多对多关系,请参见

有时候,当你的问题一被提出,你就马上解决了。这就是我学到的

我对back_populardate vs backref有点困惑。我在想,如果我添加了backref,我就不需要在另一个类中添加foreignkey,但这是不正确的

因此,对于一对多:

这是在实体中声明的

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")

关于何时使用外部表有一些模糊,但希望这也能帮助其他人。

关系是DBs外键引用上的ORM映射。在不了解它们的情况下,SQLAlchemy不知道如何查询相关的模型对象。您可以手动提供这些信息,但很少有用。您还需要实体和类别之间的关联表,以便在SQL中具有多对多关系,然后将其映射到ORM关系。关系构造的目的不是最小化键和ID的定义,而是将SQL关系映射到ORM关系。