繁体   English   中英

Flask-SQLAlchemy左外连接过滤查询

[英]Flask-SQLAlchemy Left Outer Join Filtered Query

最初我试图做一个“正确的外部加入”但是一旦我发现不支持我就开始从左边开始工作。 但是,我无法弄清楚如何写出我需要的东西。 基本上我有两个表, Table_1Table_2 ,我需要Table_1中的所有行,其中column_c等于1 另外,我需要Table_2中的所有行,其中column_b不在Table 1 在视觉上它看起来像这样:

**Table_1**
column_a ( a and b are the
column_b ( primary key.
column_c

**Table_2**
column_b

这是我在SQL中编写的方式:

SELECT *
FROM (SELECT * FROM Table_1 WHERE column_a = 123) t1
RIGHT OUTER JOIN Table_2 t2 ON t1.column_b = t2.column_b
WHERE t1.column_c = 1 or t1.column_c is NULL;

SELECT *
FROM Table_2 t2
LEFT OUTER JOIN (SELECT * FROM Table_1 WHERE column_a = 123) t1
ON Table_2 t2 ON t1.column_b = t2.column_b
WHERE t1.column_c = 1 or t1.column_c is NULL;

这就是我在Flask-SQLAlchemy形式中所做的,重要的是要注意这是Table_2的db.Model类中的一个方法。

def all_exclude(self, column_a):
    return self.query.outerjoin(
        Table_1, 
        Table_1.column_b==Table_2.column_b).filter(or_(
            Table_1.column_c==None,
            and_(Table_1.column_c==1, 
                 Table_1.column_a==column_a))).all()

不幸的是,当我编写它时,我并没有考虑它,因为我无法从类表单中调用该方法,所以它不会真正起作用。 初始化一个只能来自单行的查询后,我必须这样做,这不是我需要的。 我知道我可以像这样查询运行它:

Business.query.outerjoin(
    Table_1, 
    Table_1.column_b==Table_2.column_b).filter(or_(
        Table_1.column_c==None,
        and_(Table_1.column_c==1, 
             Table_1.column_a==column_a))).all()

但是我试图将我的课程分开以用于OOP目的,但即便如此,我认为这不会起作用,因为技术上过滤器在连接之前没有完成。 也许解决方案比我想象的要容易,但我无法完全理解它。 先感谢您!

根据您的评论,这应该回答您的问题:

SELECT Table_1.column_a, Table_1.column_b
  FROM Table_1 
 WHERE Table_1.column_a = 123
   AND Table_1.column_c = 1
 UNION
SELECT Table_2.column_a, Table_2.column_b /* I'm assuming these columns exist in Table_2. Make sure these columns are same as selected columns from Table_1 */
  FROM Table_2
 WHERE NOT EXISTS (SELECT 1 FROM Table_1 
                    WHERE Table_1.column_b = Table_2.column_b 
                      AND Table_1.column_a = 123);

这在Python SQLAlchemy中转换为:

from sqlalchemy import exists

query_1 = (db.session.query(Table_1)
           .with_entities(Table_1.column_a, Table_1.column_b)
           .filter(Table_1.column_a == 123)
           .filter(Table_1.column_c == 1)

query_2 = (db.session.query(Table_2)
           .with_entities(Table_2.column_a, Table_2.column_b)
           .filter(
               ~exists().where(Table_1.column_b == Table_2.column_b)
              )
           )
query = query_1.union(query_2).all()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM