Python Sqlalchemy双联表?

Python Sqlalchemy双联表?,python,sqlalchemy,Python,Sqlalchemy,我想通过注释表在Dataset对象和所有类别对象之间创建关联 数据集包含注释的集合。每个注释都有一个类别。我希望Dataset.categories包含由该Dataset实例中所有注释的所有类别组成的唯一类别集。我曾尝试使用双关联表(dataset\u categories)来实现这一点,但它不起作用。正确的方法是什么?以下是我目前的代码: Base = declarative_base() dataset_categories = Table('dataset_categories', Ba

我想通过注释表在Dataset对象和所有类别对象之间创建关联

数据集包含注释的集合。每个注释都有一个类别。我希望Dataset.categories包含由该Dataset实例中所有注释的所有类别组成的唯一类别集。我曾尝试使用双关联表(
dataset\u 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')

如果不要求关联只包含唯一的类别,这将与使用。一个选项是定义集合类,在定义关系时用作
set

class Dataset(Base):
    __tablename__ = 'datasets'

    id = Column(Integer, primary_key=True)
    annotations = relationship("Annotation")
    categories = relationship("Category", secondary="annotations", collection_class=set)
另一方面,
关系的次表
不必是基表,因此可以使用简单的注释选择:

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)

您是否尝试过创建
dataset\u类别中的所有列
主键?在查找表中,相关对象主键的外键本身应该是主键。它们在各自的表中都是主键是。我指的是使查找表中的外键在查找表中也显式显示主键。您的意思是:dataset_categories=table('dataset_categories',Base.metadata,Column('dataset_id',Integer,ForeignKey('dataset.id'),primary_key=True),Column('annotation_id',Integer,ForeignKey('annotations.id')),primary_key=True),列('category_id',Integer,ForeignKey('categories.id'),primary_key=True)),它们都不起作用。我想注释在您的实际实现中包含了更多信息,并且为了方便起见进行了简化?如果不是,将注释的
dataset\u id、category\u id
设置为键(唯一),将阻止您首先添加重复项。感谢您的回复。我想我实际上需要的是一个
列\u属性
,我想我可以使用后面的查询来获得它。Dataset类应该只能通过其与图像的关系访问注释和类别对象。所以可能类似于,
column\u属性(选择([annotations.c.dataset\u id,annotations.c.category\u id])。\distinct()。\alias()