简体   繁体   English

从 SqlAlchemy 表中获取所有列以对其进行过滤

[英]Get all columns from a SqlAlchemy table to filter on them

I build default equal filters for all columns of the table and then add/override only specific filters I want on a few columns, like this:我为表的所有列构建默认的相等过滤器,然后仅在几列上添加/覆盖我想要的特定过滤器,如下所示:

# Table definition

class OrderTable(Base):
    __tablename__ = "orders"

    id = Column(Integer, unique=True, nullable=False, primary_key=True)
    name = Column(String, nullable=False)

# Build all default filters for this table

table_filters = {column.name: lambda value: column == value for column in OrderTable.__table__.columns}

# Add/override specific filters

all_filters = {**table_filters, "name": lambda value: OrderTable.name.like(value)}

# Execute the query

query = ...
query = query.filter(all_filters["id"](123)) 
query.delete()

But I get this warning when using default filters:但是我在使用默认过滤器时收到此警告:

SAWarning: Evaluating non-mapped column expression 'orders.id' onto ORM instances; this is a deprecated use case.  Please make use of the actual mapped columns in ORM-evaluated UPDATE / DELETE expressions.

Is there a better way to get all columns to be able to filter on them without getting this warning?有没有更好的方法让所有列能够在不收到此警告的情况下对其进行过滤?

I tried different ways of gettings all columns for a table with OrderTable.__mapper__.attrs and inspect(OrderTable).attrs but then the filters do not work.我尝试了不同的方法来使用OrderTable.__mapper__.attrsinspect(OrderTable).attrs获取表的所有列,但是过滤器不起作用。

I am not used to post so please tell me if I can improve my question and I will edit it.我不习惯发帖,所以请告诉我是否可以改进我的问题,我会对其进行编辑。

It appears to be related to fetching columns from the table vs using attributes directly.它似乎与从表中获取列与直接使用属性有关。

When you use the attibute directly, you get an InstrumentedAttribute , when you get the column from __table__.columns you get a Column .当您直接使用 attibute 时,您会得到一个InstrumentedAttribute ,当您从__table__.columns中获取列时,您会得到一个Column

With the Column you get that warning:使用该Column ,您会收到该警告:

id_filter_col = OrderTable.__table__.c["id"] == 1

query = session.query(OrderTable)
query = query.filter(id_filter_col)
query.delete()  # SAWarning: Evaluating non-mapped column expression 'orders.id' onto ORM instances...

But now when you use the InstrumentedAttribute :但是现在当您使用InstrumentedAttribute时:

id_filter_attr = OrderTable.id == 2

query = session.query(OrderTable)
query = query.filter(id_filter_attr)
query.delete()  # OK

You can access the attributes from the mapper via __mapper__.all_orm_descriptors , which should solve your problem.您可以通过__mapper__.all_orm_descriptors从映射器访问属性,这应该可以解决您的问题。

class OrderTable(Base):
    __tablename__ = "orders"

    id = Column(Integer, unique=True, nullable=False, primary_key=True)
    name = Column(String, nullable=False)

table_filters = {column.key: lambda value: column == value for column in OrderTable.__mapper__.all_orm_descriptors}

all_filters = {**table_filters, "name": lambda value: OrderTable.name.like(value)}

query = ...
query = query.filter(all_filters["id"](123)) 
query.delete()  # OK

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

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