[英]How to use sum and count in a joined query on sqlAlchemy models
I have working SQL that I need to represent in a working Flask app that is using SQLAlchemy as an ORM. 我有需要在使用SQLAlchemy作为ORM的Flask应用程序中表示的工作SQL。 I can represent the joins, etc., but am getting nowhere with tying in the sums, counts, and the other specific select element, u.firstname || ' ' || u.lastname
我可以表示联接等,但是将总和,计数和其他特定的选择元素u.firstname || ' ' || u.lastname
捆绑在一起u.firstname || ' ' || u.lastname
u.firstname || ' ' || u.lastname
u.firstname || ' ' || u.lastname
. u.firstname || ' ' || u.lastname
。
SQL 的SQL
select
u.firstname || ' ' || u.lastname SELLER,
count(i.id) UNIQUE_ITEMS,
sum(i.qty) ITEMS_TOTAL,
sum(i.qty * p.price) ORDER_AMOUNT
from
orders o
INNER JOIN order_items i
on o.id = i.order_id
and o.campaign_id = 133
INNER JOIN products p
ON i.product_id = p.id
INNER JOIN users u
ON o.user_id = u.id
GROUP BY u.id
ORDER BY sum(i.qty) DESC, sum(i.qty * p.price) DESC;
and working Flask implementation: 和有效的Flask实施:
orders = Order.query.filter_by(campaign_id=campaign_id).
join(OrderItem).
join(Product).
join(User).
order_by(OrderItem.qty.desc())
If I add group_by(User.id)
it complains as well that I haven't placed in every other element from Order
. 如果我添加group_by(User.id)
它也会抱怨我没有放置Order
中的所有其他元素。
In case the functions are the issue, I'm running against a Postgres 9.5 如果功能是问题,我正在使用Postgres 9.5
You're trying to query the Order
, but that's not what you are querying in your raw SQL. 您正在尝试查询Order
,但这不是您在原始SQL中查询的内容。 You need something like: 您需要类似:
query = session.query(
(User.first_name + ' ' + User.last_name).label('seller'),
sa.func.count(OrderItem.id).label('unique_items'),
sa.func.sum(OrderItem.qty).label('items_total'),
sa.func.sum(OrderItem.qty * Product.price).label('order_amount'),
).join(OrderItem).join(Product).group_by(User.id).order_by('items_total',
'order_amount')
To put it all together in an example that shows you what's going on: 将其汇总为一个示例,向您展示正在发生的事情:
import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base
from decimal import Decimal
engine = sa.create_engine('sqlite:///:memory:')
Base = declarative_base()
session = sa.orm.sessionmaker(bind=engine)()
class OrderItem(Base):
__tablename__ = 'order'
id = sa.Column('id', sa.Integer, primary_key=True)
product_id = sa.Column('product_id', sa.Integer, sa.ForeignKey('product.id'))
user_id = sa.Column('user_id', sa.Integer, sa.ForeignKey('user.id'))
qty = sa.Column('qty', sa.Integer)
class Product(Base):
__tablename__ = 'product'
id = sa.Column('id', sa.Integer, primary_key=True)
price = sa.Column('price', sa.Numeric(14,2))
class User(Base):
__tablename__ = 'user'
id = sa.Column('id', sa.Integer, primary_key=True)
first_name = sa.Column('first_name', sa.Text)
last_name = sa.Column('last_name', sa.Text)
Base.metadata.create_all(engine)
engine.echo = True
session.add(User(id=42, first_name='John', last_name='Cleese'))
session.add(User(id=13, first_name='Sir', last_name='Robin'))
session.add(Product(id=1, price=Decimal('2.10')))
session.add(OrderItem(product_id=1, user_id=42, qty=9))
session.add(OrderItem(product_id=1, user_id=42, qty=2))
session.add(OrderItem(product_id=1, user_id=13, qty=2))
session.add(OrderItem(product_id=1, user_id=13, qty=3))
session.add(OrderItem(product_id=1, user_id=13, qty=20))
session.commit()
query = session.query(
(User.first_name + ' ' + User.last_name).label('seller'),
sa.func.count(OrderItem.id).label('unique_items'),
sa.func.sum(OrderItem.qty).label('items_total'),
sa.func.sum(OrderItem.qty * Product.price).label('order_amount'),
).join(OrderItem).join(Product).group_by(User.id).order_by('items_total',
'order_amount')
print('{0:=^40}\n{1:^40}\n{0:=^40}'.format('=', 'Query'))
results = [row for row in session.execute(query)]
print('{0:=^40}\n{1:^40}\n{0:=^40}'.format('=', 'Results'))
for row in results:
print(dict(row))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.