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实例。