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