gpt4 book ai didi

python - 连接表中的复杂过滤器 SQLAlchemy

转载 作者:行者123 更新时间:2023-12-04 15:01:40 25 4
gpt4 key购买 nike

我有类似下面的查询

query = db.session.query(Attribute)
.select_from(Product)
.filter_by(category_id=some_id)
.join(Attribute)

哪个返回:

[(<Product 1>, <Attribute 1>),
(<Product 1>, <Attribute 3>), #two attributes for Product 1
(<Product 2>, <Attribute 2>),
(<Product 2>, <Attribute 5>), #two attributes for Product 2
...]

我需要一个查询来保留所有具有至少一个属性匹配特定 type 的产品和 value值。在上面的示例中,如果 <Attribute 1>是唯一满足这些条件的属性,结果应该是:

[(<Product 1>, <Attribute 1>), #Attribute1 met the conditions
(<Product 1>, <Attribute 3>)] #Other Product1 rows are thus kept

编辑:Product 和 Attribute 具有多对多关系,以下是模型:

class Product(db.Model):
id = db.Column(db.Integer, primary_key=True)
sku = db.Column(db.String(10), unique=True, nullable=False)
category_id = db.Column(db.Integer, db.ForeignKey('category.id'), nullable=False)
category = db.relationship('Category', backref=db.backref('products', lazy=True))

class ProductAttribute(db.Model):
product_id = db.Column(db.Integer, db.ForeignKey('product.id'), primary_key=True)
attribute_id = db.Column(db.Integer, db.ForeignKey('attribute.id'), primary_key

class Attribute(db.Model):
id = db.Column(db.Integer, primary_key=True)
type = db.String(db.String(40))
value = db.String(db.String(40))

最佳答案

解决这个问题的一种方法是使用 relationship.any构造。

请在下面找到完整的示例代码,我在其中尝试猜测一个更完整的模型。即使它不完整,它也会给你一个正确方向的提示:

型号:

class Product(db.Model):
id = db.Column(db.Integer, primary_key=True)
sku = db.Column(db.String(10), unique=True, nullable=False)
category_id = db.Column(db.Integer, db.ForeignKey('category.id'), nullable=False)
category = db.relationship('Category', backref=db.backref('products', lazy=True))
# added this relationship definition
attributes = db.relationship("Attribute", secondary="product_attribute")


class ProductAttribute(db.Model):
product_id = db.Column(db.Integer, db.ForeignKey("product.id"), primary_key=True)
attribute_id = db.Column(
db.Integer, db.ForeignKey("attribute.id"), primary_key=True
)


class Attribute(db.Model):
id = db.Column(db.Integer, primary_key=True)
type = db.Column(db.String(40))
value = db.Column(db.String(40))

测试数据:

attrs = ac_b, ac_w, as_l, as_s, ah_y, ah_n = [
Attribute(type="color", value="black"),
Attribute(type="color", value="green"),
Attribute(type="size", value="large"),
Attribute(type="size", value="small"),
Attribute(type="healthy", value="yes"),
Attribute(type="healthy", value="not that much"),
]

prods = [
Product(sku="no-attribs", attributes=[]),
Product(sku="black-only", attributes=[ac_b]),
Product(sku="black-larg", attributes=[ac_b, as_l]),
Product(sku="white-col", attributes=[ac_w, as_s]),
Product(sku="no-colors", attributes=[ah_y, as_s]),
]

db.session.add_all(attrs + prods)

ANSWER:查询

query = (
db.session.query(Product, Attribute)
# .select_from(Product) # this could be removed if `Product` is included in the query above
.join(Attribute, Product.attributes)
# .filter_by(category_id=some_id) # this one can be added, but not used in tests
.filter(Product.attributes.any(
# HERE you can put any combination of filters on the 'Attribute' you need
and_(
Attribute.type == 'color',
Attribute.value == 'black',
)
))
)

生成的 SQL:在 postgres 上它应该如下所示:

SELECT product.id,
product.sku,
attribute.id,
attribute.type,
attribute.value
FROM product
JOIN product_attribute AS product_attribute_1 ON product.id = product_attribute_1.product_id
JOIN attribute ON attribute.id = product_attribute_1.attribute_id
WHERE EXISTS
(SELECT 1
FROM product_attribute,
attribute
WHERE product.id = product_attribute.product_id
AND attribute.id = product_attribute.attribute_id
AND attribute.type = %(type_1)s
AND attribute.value = %(value_1)s)

查询结果:

从下面可以看出,从测试数据来看,结果涵盖了所有符合要求的产品的所有属性(有“color”=“black”):

(<Product(id=3, sku='black-larg')>, <Attribute(id=1, type='color', value='black')>)
(<Product(id=3, sku='black-larg')>, <Attribute(id=3, type='size', value='large')>)
(<Product(id=2, sku='black-only')>, <Attribute(id=1, type='color', value='black')>)

关于python - 连接表中的复杂过滤器 SQLAlchemy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66851805/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com