Python SQLAlchemy中ForeignKey上的查询过滤器
为了简化,我有两个表(ORM FastAPI) 一个对象可以有多个属性(1-N关系)。 属性是动态的(取决于对象,某些对象有10个属性,或50个…) 例如:Python SQLAlchemy中ForeignKey上的查询过滤器,python,sqlalchemy,orm,fastapi,Python,Sqlalchemy,Orm,Fastapi,为了简化,我有两个表(ORM FastAPI) 一个对象可以有多个属性(1-N关系)。 属性是动态的(取决于对象,某些对象有10个属性,或50个…) 例如: Object | Attributes --------------------------------- Object 1 | color = red | form = round | level = 5 | ... | att
Object | Attributes
---------------------------------
Object 1 | color = red
| form = round
| level = 5
| ...
| attribute alpha
---------------------------------
Object 2 | color = red
| form = square
| level = 2
| ...
| attribute beta
我想做一些类似的事情:
“查找定义了attribute.color=red、attribute.level>=2和attribute.X的所有对象”
我试过:
query = db.query(Object).options(
joinedload(Attributes,innerjoin=False)).join(Attributes)
query = query.filter(Attributes.attribute == 'color')
query = query.filter(Attributes.value == 'red')
...
return query.all()
但是我不知道如何在表属性上级联过滤器
感谢您的帮助…要实现过滤器,我将使用: 这将生成SQL语句(具体取决于DB引擎):
这正是我丢失的代码,谢谢!!!!
query = db.query(Object).options(
joinedload(Attributes,innerjoin=False)).join(Attributes)
query = query.filter(Attributes.attribute == 'color')
query = query.filter(Attributes.value == 'red')
...
return query.all()
query = (
session.query(Object)
# -- NOTE: below join is not needed for the filter part;
# .options(joinedload(Attributes, innerjoin=False))
# .join(Attributes)
# add additional criteria
.filter(
Object.attributes.any(
and_(
Attributes.attribute == "color",
Attributes.value == "red",
)
)
)
.filter(
Object.attributes.any(
and_(
Attributes.attribute == "level",
func.cast(Attributes.value, Integer) >= 2,
)
)
)
.filter(Object.attributes.any(Attributes.attribute == "X")) # exists
)
SELECT object.id,
object.name
FROM object
WHERE (EXISTS
(SELECT 1
FROM attributes
WHERE object.id = attributes.parent_id
AND attributes.attribute = 'color'
AND attributes.value = 'red'))
AND (EXISTS
(SELECT 1
FROM attributes
WHERE object.id = attributes.parent_id
AND attributes.attribute = 'level'
AND CAST(attributes.value AS INTEGER) >= 2))
AND (EXISTS
(SELECT 1
FROM attributes
WHERE object.id = attributes.parent_id
AND attributes.attribute = 'X'))