Python SQLAlchemy 3路连接查询

Python SQLAlchemy 3路连接查询,python,sqlite,sqlalchemy,Python,Sqlite,Sqlalchemy,我见过关于这方面的其他问题,但没有一个完全符合要求。 我正在写一个应用程序,可以对一组音乐数据进行各种查询。我的问题是: 假设我有这样一门乐器课: class Instrument(Base, NamedMixin): diatonic = Column(Integer, default=0) chromatic = Column(Integer, default=0) pieces = relationship( "Piece", s

我见过关于这方面的其他问题,但没有一个完全符合要求。 我正在写一个应用程序,可以对一组音乐数据进行各种查询。我的问题是: 假设我有这样一门乐器课:

class Instrument(Base, NamedMixin):

    diatonic = Column(Integer, default=0)
    chromatic = Column(Integer, default=0)

    pieces = relationship(
        "Piece",
        secondary=instrument_join_table,
        back_populates="instruments",
        lazy='dynamic')

    clefs = relationship(
        "Clef",
        secondary=clef_join_table,
        back_populates="instruments",
        lazy="dynamic"
    )

    keys = relationship(
        "Key",
        secondary=key_join_table,
        back_populates="instruments",
        lazy="dynamic"
    )
class Clef(Base, NamedMixin):
    sign = Column(String)
    line = Column(Integer)

    pieces = relationship(
        "Piece",
        secondary=clef_join_table,
        back_populates="clefs",
        lazy='dynamic')

    instruments = relationship(
        "Instrument",
        secondary=clef_join_table,
        back_populates="clefs",
        lazy="dynamic"
        )
class Piece(Base, NamedMixin):
    instruments = relationship(
        "Instrument",
        secondary=instrument_join_table,
        back_populates="pieces", lazy='dynamic')

    clefs = relationship(
        "Clef",
        secondary=clef_join_table,
        back_populates="pieces", lazy='dynamic')

    keys = relationship(
        "Key",
        secondary=key_join_table,
        back_populates="pieces", lazy='dynamic')
还有一个叫做谱号的音乐元素类,如下所示:

class Instrument(Base, NamedMixin):

    diatonic = Column(Integer, default=0)
    chromatic = Column(Integer, default=0)

    pieces = relationship(
        "Piece",
        secondary=instrument_join_table,
        back_populates="instruments",
        lazy='dynamic')

    clefs = relationship(
        "Clef",
        secondary=clef_join_table,
        back_populates="instruments",
        lazy="dynamic"
    )

    keys = relationship(
        "Key",
        secondary=key_join_table,
        back_populates="instruments",
        lazy="dynamic"
    )
class Clef(Base, NamedMixin):
    sign = Column(String)
    line = Column(Integer)

    pieces = relationship(
        "Piece",
        secondary=clef_join_table,
        back_populates="clefs",
        lazy='dynamic')

    instruments = relationship(
        "Instrument",
        secondary=clef_join_table,
        back_populates="clefs",
        lazy="dynamic"
        )
class Piece(Base, NamedMixin):
    instruments = relationship(
        "Instrument",
        secondary=instrument_join_table,
        back_populates="pieces", lazy='dynamic')

    clefs = relationship(
        "Clef",
        secondary=clef_join_table,
        back_populates="pieces", lazy='dynamic')

    keys = relationship(
        "Key",
        secondary=key_join_table,
        back_populates="pieces", lazy='dynamic')
像这样的一节课:

class Instrument(Base, NamedMixin):

    diatonic = Column(Integer, default=0)
    chromatic = Column(Integer, default=0)

    pieces = relationship(
        "Piece",
        secondary=instrument_join_table,
        back_populates="instruments",
        lazy='dynamic')

    clefs = relationship(
        "Clef",
        secondary=clef_join_table,
        back_populates="instruments",
        lazy="dynamic"
    )

    keys = relationship(
        "Key",
        secondary=key_join_table,
        back_populates="instruments",
        lazy="dynamic"
    )
class Clef(Base, NamedMixin):
    sign = Column(String)
    line = Column(Integer)

    pieces = relationship(
        "Piece",
        secondary=clef_join_table,
        back_populates="clefs",
        lazy='dynamic')

    instruments = relationship(
        "Instrument",
        secondary=clef_join_table,
        back_populates="clefs",
        lazy="dynamic"
        )
class Piece(Base, NamedMixin):
    instruments = relationship(
        "Instrument",
        secondary=instrument_join_table,
        back_populates="pieces", lazy='dynamic')

    clefs = relationship(
        "Clef",
        secondary=clef_join_table,
        back_populates="pieces", lazy='dynamic')

    keys = relationship(
        "Key",
        secondary=key_join_table,
        back_populates="pieces", lazy='dynamic')
所以我在乐器、曲子和谱号以及乐器、键和谱号之间定义了一种多对多对多的关系。乐器联接表将乐曲id和乐器id联接在一个表中,谱号联接和键联接表包含乐曲id、乐器id和谱号id。相关联接:

instrument_join_table = Table(
'instrument_piece_join', Base.metadata, Column(
    'instrument_id', Integer, ForeignKey('instrument.id')), Column(
        'piece_id', Integer, ForeignKey('piece.id')))

clef_join_table = Table('clef_piece_join', Base.metadata,
                        Column('clef_id', Integer, ForeignKey('clef.id')),
                        Column('piece_id', Integer, ForeignKey('piece.id')),
                        Column('instrument_id', Integer, ForeignKey('instrument.id'))
                        )

key_join_table = Table('key_piece_join', Base.metadata,
                       Column('key_id', Integer, ForeignKey('key.id')),
                       Column('piece_id', Integer, ForeignKey('piece.id')),
                       Column('instrument_id', Integer, ForeignKey('instrument.id'))
                       )
我用的是动态的基底。命名的mixin有一个name列和一个ID列

我想查询的是一个包含一个谱号的乐器的曲子。 当然,我首先查询乐器,然后按谱号过滤:

models = self.session.query(Instrument).filter_by(name=instrument)
ins_models = models.filter(Instrument.clefs.any(**kwarg)).all()
但是如果你从这两个元素中选择一个元素,你会得到乐器上有但可能不在合适的谱号中的曲子,或者包含谱号但不一定有这些乐器的曲子

在将纯SQL用于SQLite数据库之前,我已经使用过SQLAlchemy,但是我对SQLAlchemy还比较陌生,所以我无法对它进行深入了解。拥有一个新模型的最佳答案是什么,比如“KeyMapping”或者你有什么或者什么?到目前为止,我似乎只是增加了更多的过滤器,但这并没有起到多大作用

这是我在纯SQL中执行此操作时使用的查询:

SELECT clef_piece.piece_id FROM clef_piece_join clef_piece WHERE EXISTS (SELECT * FROM clef_piece_join WHERE piece_id = clef_piece.piece_id AND instrument_id = ? AND clef_id = ?)

然后,对于我添加到内部select的每个谱号,以及添加和存在的每个乐器(另一个select查询)。

您的问题中是否也包括关联(联接)表本身?“…但是如果你要求这两种元素中的任何一种,你将得到乐器拥有但可能不在适当谱号中的片段。。。“,您的意思是,如果您迭代例如
instrument.pieces
clef.pieces
,其中
instrument
clef
是您查询的结果吗?至于原始SQL,为什么
存在半连接
clef\u-piece\u-join
,然后检查instrument和clef的
?这还不够吗?由于该查询显示该表中有所有必需的信息,因此也可以将其与SQLAlchemy一起使用;查询并连接
片段
以获取orm实例。您可以在问题中包括关联(连接)表本身吗?“…但是如果您从这两个元素中的任何一个元素中请求片段,您将获得仪器具有但可能不在适当谱号中的片段…”,你的意思是,如果你迭代例如
instrument.pieces
clef.pieces
,其中
instrument
clef
是你查询的结果吗?至于你的原始SQL,为什么
存在半连接
clef\u-piece\u-join
,然后检查instrument和clef的
?这还不够吗?由于该查询显示该表中有所有必需的信息,因此也可以将其与SQLAlchemy一起使用;查询并加入
片段
,以获取orm实例。