Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python SQLAlchemy,选择至少有一个带升起标志的B的A_Python_Sql_Postgresql_Sqlalchemy_One To Many - Fatal编程技术网

Python SQLAlchemy,选择至少有一个带升起标志的B的A

Python SQLAlchemy,选择至少有一个带升起标志的B的A,python,sql,postgresql,sqlalchemy,one-to-many,Python,Sql,Postgresql,Sqlalchemy,One To Many,我有两张桌子: class A(Base): id = Column(Integer, primary_key=True) class B(Base): id = Column(Integer, primary_key=True) a_id = Column(Integer, ForeignKey('a.id')) a = relationship(A) flag = Column(Boolean, default=False) 如您所见,B中的每个

我有两张桌子:

class A(Base):
    id = Column(Integer, primary_key=True)

class B(Base):
    id = Column(Integer, primary_key=True)

    a_id = Column(Integer, ForeignKey('a.id'))
    a = relationship(A)
    flag = Column(Boolean, default=False)
如您所见,B中的每个对象都与A中的一个对象相关,而且,B中的多个对象可以与A中的单个对象相关。
我需要选择所有至少有一个标志==False的相关B的A。
现在我在想这样的事情:

    selection = session.query(A).\
        join(B).\
        filter(
            B.a_id == A.id,
            B.flag == False,
        ).\
        group_by(A)
但有两件事我不确定:

  • 这个查询是否正确?(我正在处理大量数据,测试这一点相当复杂)

  • 从炼金术哲学的角度来看,这个问题是否正确?(我是新手)


  • 拟合查询将使用半联接:

    SELECT * FROM A
    WHERE  EXISTS (SELECT 1 FROM B WHERE a_id = A.id AND flag = FALSE);
    
    为了快速实现这一点,您应该在
    B
    上使用
    a_id
    作为唯一或第一个表达式的任何索引。如果条件为“代码> >标志=false 是常见的,请考虑<强>部分索引< /强>,如:

    CREATE INDEX b_some_nmae_idx ON b(a_id) WHERE flag = FALSE;
    

    连接到
    B
    中所有匹配的行并再次聚合(就像您在问题中所做的那样)是一项毫无意义的工作<代码>存在可以在找到
    B
    中的第一个匹配行后立即停止。

    在关系中添加一个
    backref

    class B(Base):
        # ...
        a = relationship(A, backref="b_s")
    
    然后@Erwin的
    SQL
    版本的
    sqlalchemy
    verino如下:

    qry = session.query(A).filter(A.b_s.any(B.flag == False))
    
    如果您不想或无法将
    backref
    添加到关系中,下面将为简单的case生成相同的查询,但您应该关注生成的
    SQL
    ,以防您有更复杂的查询,因为连接可能需要更多的调整:

    qry = (session.query(A).filter(
        exists(select([1]).where(B.a_id == A.id).where(B.flag == False)))
    )
    

    谢谢你的回答。事实上,我知道如何在原始SQL中执行此操作:)我需要使用sqlalchemy执行相同的操作。@sennoy:正如我在回答中添加的:您现在的查询不是SQL中的最佳选择。是否可以不使用backref?