SQLAlchemy 3方式连接查询

时间:2016-08-25 23:56:16

标签: python sqlite sqlalchemy

我已经看到了其他问题,但他们都没有完全适合这个法案。 我正在编写一个应用程序,它对一组音乐数据运行各种查询。我遇到的问题是: 假设我有一个这样的乐器类:

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

因此,我在乐器,乐曲和谱号,乐器,琴键和谱号之间定义了多对多的关系。仪器连接表将piece id和instrument id连接在一个表中,clef_join和key_join表包含piece id,instrument id和clef 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有一个名称列和一个ID列。

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

models = self.session.query(Instrument).filter_by(name=instrument)
ins_models = models.filter(Instrument.clefs.any(**kwarg)).all()

但是如果你要求这两个元素中的任何一个的碎片,你将获得乐器所具有的碎片但可能没有合适的谱号,或者包含谱号但不一定具有碎片的碎片仪器

在使用SQLAlchemy将纯SQL用于SQLite数据库之前,我已经完成了这项工作,但我对SQLAlchemy相对较新,所以无法解决这个问题。拥有一个新模型是最好的答案,比如“InstrumentClefKeyMapping”或者你有什么或者什么?到目前为止,我似乎只是投入了更多的过滤器而没有做太多。

这是我在纯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 = ?)

然后,对于每个谱号,我添加到内部选择,每个乐器添加AND EXISTS(另一个选择查询)。

0 个答案:

没有答案