我是一个尝试使用sqlalchemy烧瓶的菜鸟,并且我从一个基本查询中排序问题。
我有一个父表和两个加入多对多关联表:
class Product(db.Model):
id = db.Column(db.Integer, primary_key=True)
(...)
qty_stock = db.Column(db.Integer)
requested_products = db.relationship('RequestedProducts')
ordered_products = db.relationship('OrderedProducts')
class OrderedProducts(db.Model):
__tablename__ = 'orderedproducts'
order_id = db.Column(db.Integer, db.ForeignKey('order.id'), primary_key=True)
product_id = db.Column(db.Integer, db.ForeignKey('product.id'), primary_key=True)
quantity = db.Column(db.Integer, default=1)
qty_delivered = db.Column(db.Integer, default=0)
product = db.relationship('Product', backref='order_assocs')
class RequestedProducts(db.Model):
__tablename__ = 'requestedproducts'
request_id = db.Column(db.Integer, db.ForeignKey('request.id'), primary_key=True)
product_id = db.Column(db.Integer, db.ForeignKey('product.id'), primary_key=True)
quantity = db.Column(db.Integer, default=1)
qty_supplied = db.Column(db.Integer, default=0)
product = db.relationship('Product', backref='request_assocs')
在我的视图类中,每个产品有4个表格列,显示库存数量,请求产品数量,订购产品数量和净库存量,基本上(库存数量 - 请求+订购)。这是我试图开始工作的净股票价值的查询:
products = Product.query.filter_by(active_flg=True)
.filter_by(category_id=int(g.category_id))
.outerjoin(Product.requested_products)
.outerjoin(Product.ordered_products)
.group_by(Product.id)
#Count requested amount for each product
reqs = func.coalesce((func.sum(RequestedProducts.quantity) - func.sum(RequestedProducts.qty_supplied)), 0)
#Count ordered amount for each product
ords = func.coalesce((func.sum(OrderedProducts.quantity) - func.sum(OrderedProducts.qty_delivered)), 0)
result = (Product.qty_stock - reqs + ords)
products = products.order_by(result.desc())
现在,函数按预期工作,唯一的问题是order_by函数 - 订单被扰乱。我发现原因可能在双外连接中。有没有人知道如何处理?
另外,我真的是sqlalchemy和flask的初学者,所以我非常感谢任何建议或更好的解决方案(可执行的技能有限)。谢谢!
答案 0 :(得分:2)
如果您已经将混合属性用于部分和,那么将它们组合在一起应该非常容易。
class Product(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
qty_stock = db.Column(db.Integer)
requested_products = db.relationship('RequestedProducts')
ordered_products = db.relationship('OrderedProducts')
@hybrid_property
def diff_orders(self):
return sum(op.quantity - op.qty_delivered
for op in self.ordered_products)
@diff_orders.expression
def diff_orders(cls):
return (db.select([db.func.coalesce(
db.func.sum(
db.func.coalesce(
OrderedProducts.quantity - OrderedProducts.qty_delivered, 0)
), 0)])
.where(OrderedProducts.product_id == cls.id)
.label("diff_orders")
)
@hybrid_property
def diff_requests(self):
return sum(op.quantity - op.qty_supplied
for op in self.requested_products)
@diff_requests.expression
def diff_requests(cls):
return (db.select([db.func.coalesce(
db.func.sum(
db.func.coalesce(
RequestedProducts.quantity - RequestedProducts.qty_supplied, 0)
), 0)])
.where(RequestedProducts.product_id == cls.id)
.label("diff_requests")
)
在哪种情况下,使用可以类似于:
products = db.session.query(
Product,
# Product.diff_orders,
# Product.diff_requests,
# Product.qty_stock + Product.diff_requests - Product.diff_orders,
).order_by((Product.qty_stock + Product.diff_requests - Product.diff_orders).desc())
for x in products:
print(x)