python - SQLAlchemy 查询和_/或_问题

标签 python sql sqlalchemy

我有一个正在尝试构建的查询。该查询似乎分部分工作,查询的两个单独部分都返回正确数量的元素。但是,组合查询返回一个空结果集,这是不正确的。

注意:我知道查询 1 和查询 2 不需要 and_,但我想确保 and_ 按预期工作。

查询 1:

  • SQLAlchemy 查询

    session.query(Lobby).filter(
        and_(
            Lobby.id == spectator_table.c.lobby_id,
            spectator_table.c.player_id == player.steamid
        )
    ).all()
    
  • 生成的 SQL

    SELECT lobby.id AS lobby_id, lobby.name AS lobby_name, lobby.owner_id AS lobby_owner_id
    FROM lobby, spectator
    WHERE lobby.id = spectator.lobby_id AND spectator.player_id = ?
    

查询 2:

  • SQLAlchemy 查询

    session.query(Lobby).filter(
        and_(
            Lobby.id == Team.lobby_id,
            LobbyPlayer.team_id == Team.id,
            LobbyPlayer.player_id == player.steamid
        )
    ).all()
    
  • 生成的 SQL

    SELECT lobby.id AS lobby_id, lobby.name AS lobby_name, lobby.owner_id AS lobby_owner_id
    FROM lobby, team, lobby_player
    WHERE lobby.id = team.lobby_id AND lobby_player.team_id = team.id AND lobby_player.player_id = ?
    

组合查询:

  • SQLAlchemy 查询

    session.query(Lobby).filter(
        or_(
            and_(
                Lobby.id == Team.lobby_id,
                LobbyPlayer.team_id == Team.id,
                LobbyPlayer.player_id == player.steamid
            ), and_(
                Lobby.id == spectator_table.c.lobby_id,
                spectator_table.c.player_id == player.steamid
            )
        )
    ).all()
    
  • 生成的 SQL

    SELECT lobby.id AS lobby_id, lobby.name AS lobby_name, lobby.owner_id AS lobby_owner_id
    FROM lobby, team, lobby_player, spectator
    WHERE lobby.id = team.lobby_id AND lobby_player.team_id = team.id AND lobby_player.player_id = ? OR lobby.id = spectator.lobby_id AND spectator.player_id = ?
    

模型

spectator_table = Table('spectator', Base.metadata,
    Column('lobby_id', Integer, ForeignKey('lobby.id'), primary_key=True),
    Column('player_id', Integer, ForeignKey('player.steamid'),
        primary_key=True
    ),
)

class Lobby(Base):
    __tablename__ = 'lobby'
    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)
    owner_id = Column(Integer, ForeignKey('player.steamid'), nullable=False,
        unique=True
    )
    teams = relationship("Team", backref="lobby",
        cascade='save-update,merge,delete'
    )
    spectators = relationship("Player", secondary=spectator_table)

class Team(Base):
    __tablename__ = 'team'
    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)
    lobby_id = Column(Integer, ForeignKey('lobby.id'), nullable=False)
    players = relationship("LobbyPlayer", backref="team",
        cascade='save-update,merge,delete,delete-orphan'
    )

class LobbyPlayer(Base):
    __tablename__ = 'lobby_player'
    team_id = Column(Integer, ForeignKey('team.id'), primary_key=True)
    player_id = Column(Integer, ForeignKey('player.steamid'), primary_key=True)
    player = relationship("Player", uselist=False)
    cls = Column(Integer)

class Player(Base):
    __tablename__ = 'player'
    steamid = Column(Integer, primary_key=True)

感谢您的帮助!

最佳答案

我在 SA 0.7.9 上看到了同样的问题

似乎令人高兴的是括号没有按照您希望的方式正确应用。我使用了 self_group() 来完成这项工作,但问题是你不应该使用它。这是文档 self_group .我认为应该有比我的更好的答案,但是,这应该让你继续。

query = session.query(Lobby).filter(
    ((Lobby.id == Team.lobby_id) &
    (LobbyPlayer.team_id == Team.id) &
    (LobbyPlayer.player_id == player.steamid)).self_group() |
    ((Lobby.id == spectator_table.c.lobby_id) &
    (spectator_table.c.player_id == player.steamid)).self_group()).all()

生成的sql如下,我相信这就是你所追求的。

SELECT lobby.id AS lobby_id, lobby.name AS lobby_name, lobby.owner_id AS lobby_owner_id 
FROM lobby, team, lobby_player, spectator 
WHERE (lobby.id = team.lobby_id AND lobby_player.team_id = team.id AND lobby_player.player_id = ?) OR (lobby.id = spectator.lobby_id AND spectator.player_id = ?)

关于python - SQLAlchemy 查询和_/或_问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13370993/

相关文章:

python - Python 2.x 中的字符串使用哪种编码?

mysql - 不同表的列上的唯一键

sql - 是否可以在 Firebird 中重命名表?

python - 让python脚本在unix的后台运行

python - 两个仅影响零值的稀疏矩阵的点积

python - 在Python中使用OpenCV库对图像进行阈值处理,并使用for循环使用不同的标志

mysql - 使用UNION/INNER JOIN使用SQL连接3个表来绘制数据

python - SQLAlchemy 3个表之间的关系

python - 我应该创建映射器对象还是使用 SQLAlchemy 中的声明性语法?

python - 通过 sqlalchemy 针对 MySql 运行的查询比在数据库控制台上慢得多