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.
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
.
With the Column
you get that warning:
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
:
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.
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.