Python SQLAlchemy核心-将Where条件添加到预先存在的select(…)

Python SQLAlchemy核心-将Where条件添加到预先存在的select(…),python,python-3.x,sqlalchemy,Python,Python 3.x,Sqlalchemy,我想创建一个函数,它接受一个通用的select,该函数假定select中存在一个特定的列,然后在此列上添加一个where条件。以下是设置: from sqlalchemy import Table, Column, Integer, String, MetaData from sqlalchemy import select metadata = MetaData() Foo = Table( 'foos', metadata, Column('id', Integer),

我想创建一个函数,它接受一个通用的
select
,该函数假定select中存在一个特定的列,然后在此列上添加一个where条件。以下是设置:

from sqlalchemy import Table, Column, Integer, String, MetaData
from sqlalchemy import select

metadata = MetaData()

Foo = Table(
    'foos', metadata,
    Column('id', Integer),
    Column('foo', String),
    Column('status', String),
)

Bar = Table(
    'bars', metadata,
    Column('id', Integer),
    Column('bar', String),
    Column('status', String),
)

下面是我想要的,但是它会产生一个自然连接:

def add_common_where_conditions(sel):
    return sel.where(sel.c.status == 'ACTIVE')

def get_foos():
    sel = select([Foo])
    sel = add_common_where_conditions(sel)
    print(sel)

def get_bars():
    sel = select([Bar])
    sel = add_common_where_conditions(sel)
    print(sel)
get\u foos()
的输出是:

SELECT foos.id, foos.foo, foos.status 
FROM foos, (SELECT foos.id AS id, foos.foo AS foo, foos.status AS status 
FROM foos) AS anon_1 
WHERE anon_1.status = :status_1
我不确定如何获得原始表的引用。例如,我尝试了这个方法,但它只得到对子查询的引用:

>>> sel = select([Foo])
>>> sel.c[0].table
<sqlalchemy.sql.selectable.Subquery at 0x1d360b7dba8; anon_1>
>>sel=select([Foo])
>>>sel.c[0]。表

我想您应该使用
选择
的属性:

sel=select([Foo])
sel=sel.where(sel.froms[0].c.status=='Active')
打印(sel)
产生

选择foos.id、foos.foo、foos.status
来自福斯
其中foos.status=:status_1

在SQLAlchemy 1.4中,您可以使用新属性,文档中说该属性可用于以下用途:

def add_common_where_conditions(sel):
    return sel.where(sel.selected_columns.status == 'ACTIVE')

sel = select([Foo])

print(add_common_where_conditions(sel))
这将产生预期的结果:

SELECT foos.id, foos.foo, foos.status 
FROM foos 
WHERE foos.status = :status_1
但是,使用这种方法,无法将where条件应用于未在选定列中指定的列。例如,这将失败:

sel = select([Foo.c.id])
sel = sel.where(sel.selected_columns.foo = 'hello')

它可以工作,但假定select的第一列来自包含要应用where子句的列的表。如果select正在查询单个表,那么这将始终有效,但对于联接,它可能会失败。当然,您可以自己循环
froms
并找出答案。我刚刚发布了一篇文章,使用了新的
selected_列
,该列在1.4版中提供,看起来效果不错。唯一的问题是大多数人都是1.3或更低。如果在1.3中有一种本机方法来实现这一点,那就太好了……是的,对于多个表,您必须找到正确的表。此
selected\u columns
的一个问题是(从名称可以推断),您只能将where条件应用于选定的列。例如,如果您想选择A和B,但在C上进行筛选,
selected\u列
将不起作用。在这种情况下,
froms
会更好,因为您可以访问基础表上的所有列,而不仅仅是所选列。