所以,我有一个 Product 类和一个 User 类。用户是产品的卖家,可以拥有许多产品。
Product.price
是不含增值税的价格,每个用户在用户表中都有一个标志is_vat
,用于说明对外显示的价格是否需要添加增值税。
所以我想创建一个按价格排序的查询,并决定创建一个混合属性(
show_price
),以便我能够按外部显示的价格进行排序。 Hybrid_property 检查卖家是否选中了 is_vat
标志,然后根据是否应添加增值税来计算向外显示的价格。
所以,问题是,查询结果是按
Product.price
排序的,而不是Product.show_price
,我不明白我到底做错了什么?
这是我正在使用的查询(Flask-sqlalchemy 和旧的 sqlalchemy 语法):
products_query = db.session.query(Product)
products = products_query.order_by(Product.show_price.desc()).all()
这是具有 Hybrid_property 的 Product 类:
class Product(db.Model):
id = db.Column(db.Integer, primary_key=True)
price = db.Column(db.Integer)
seller_id = db.Column(db.Integer, db.ForeignKey('user.id'))
@hybrid_property
def show_price(self):
is_vat = db.session.query(User.is_vat).filter(User.id == self.seller_id).first()[0]
if is_vat == True:
return (self.price * 1.25)
if is_vat == False or is_vat == None:
return (self.price * 1.0)
问题是Python代码不能直接在SQL语句中使用。要使条件发挥作用,需要翻译。
association_proxy
设置为 is_vat
属性。然后为使用 expression
语句的 hybrid_property
添加 case
。这用于为查询创建实际的 SQL 语句。
从那时起,排序应该根据条件按值进行排序。
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy import case
class Product(db.Model):
id = db.Column(db.Integer, primary_key=True)
price = db.Column(db.Integer)
seller_id = db.Column(db.Integer, db.ForeignKey('user.id'))
seller = db.relationship('User')
is_vat = association_proxy('seller', 'is_vat')
@hybrid_property
def show_price(self):
return (self.price * 1.25) if self.is_vat else (self.price * 1.0)
@show_price.expression
def show_price(cls):
return case(
(cls.is_vat == True, cls.price * 1.25),
else_=cls.price * 1.0
)