繁体   English   中英

Sqlalchemy 双关联表?

[英]Sqlalchemy double association table?

我想通过注释表在数据集 object 和所有类别对象之间创建关联。

数据集包含注释的集合。 每个注释都有一个类别。 我希望 Dataset.categories 包含由该 Dataset 实例中所有注释的所有类别组成的唯一类别集。 我曾尝试使用双重关联表( dataset_categories )来执行此操作,但它不起作用。 这样做的正确方法是什么? 到目前为止,这是我的代码:

Base = declarative_base()

dataset_categories = Table('dataset_categories', Base.metadata,
    Column('dataset_id', Integer, ForeignKey('datasets.id')),
    Column('annotation_id', Integer, ForeignKey('annotations.id')),
    Column('category_id', Integer, ForeignKey('categories.id')))

class Dataset(Base):
    __tablename__ = 'datasets'

    id = Column(Integer, primary_key=True)
    annotations = relationship("Annotation")
    categories = relationship("Category", secondary=dataset_categories)

class Annotation(Base):
    __tablename__ = 'annotations'
    id = Column(Integer, primary_key=True)
    category_id = Column(Integer, ForeignKey('categories.id'), nullable=False)
    category = relationship("Category")
    dataset_id = Column(Integer, ForeignKey('datasets.id'))

class Category(Base):
    __tablename__ = 'categories'
    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False, unique=True)
    dataset = relationship("Dataset", secondary=dataset_categories)
    dataset_id = Column(Integer, ForeignKey('datasets.id'),
                        back_populates='categories')

如果不要求关联仅包含唯一类别,这将与使用association_proxy一样简单。 一种选择是定义集合 class 以在定义关系时按set使用:

class Dataset(Base):
    __tablename__ = 'datasets'

    id = Column(Integer, primary_key=True)
    annotations = relationship("Annotation")
    categories = relationship("Category", secondary="annotations", collection_class=set)

另一方面, relationship的辅助表不必是基表,因此可以使用注释中的简单 select:

class Dataset(Base):
    __tablename__ = 'datasets'

    id = Column(Integer, primary_key=True)
    annotations = relationship("Annotation")
    categories = relationship("Category",
                              secondary="""select([annotations.c.dataset_id,
                                                   annotations.c.category_id]).\\
                                           distinct().\\
                                           alias()""",
                              viewonly=True)

暂无
暂无

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

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