2017-01-04 2 views
0

SQLAlchemy를 ORM으로 사용하는 작업용 Flask 응용 프로그램에서 나타내는 데 필요한 SQL을 작업하고 있습니다. 조인 등을 나타낼 수는 있지만 합계, 개수 및 다른 특정 선택 요소 인 u.firstname || ' ' || u.lastname을 묶는 데는 아무런 변화가 없습니다.sqlAlchemy 모델의 조인 된 쿼리에서 sum 및 count를 사용하는 방법

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; 

및 작업 플라스크 구현 : 나는 group_by(User.id)를 추가하면 그것뿐만 아니라 내가 Order에서 다른 모든 요소에 배치되지 않았 음을 불평

orders = Order.query.filter_by(campaign_id=campaign_id). 
    join(OrderItem). 
    join(Product). 
    join(User). 
    order_by(OrderItem.qty.desc()) 

.

는 경우 기능은 I 당신은 Order를 조회하려는 포스트 그레스 9.5

+0

내가 쿼리를 재현하기 위해'sqlalchemy.sql.select'을 시도 할 것입니다. –

+0

물론'session.execute ()'일 수도 있지만 더 많은 SQLAlchemy 구조화 된 방법이 있다는 것을 알았습니다. 받아 들여진 응답은 나가 예상하고 있던 무슨이었다. 고마워. –

+0

웨인의 대답은 아주 좋습니다. 나는'session.execute'와'sqlalchemy.sql.select'를 비교하지 않을 것이고, 두 번째는'session.query'와 훨씬 비슷합니다. 여러분은 SQL 대응 부분과 같은 이름을 가진 메소드를 연결하기 만하면됩니다. –

답변

1

에 대해 실행하고있어,이 문제입니다,하지만 당신은 당신의 원시 SQL에서 쿼리하는 게 아니에요. 무슨 일이 일어나고 있는지를 보여주는 예제에 모두 함께 넣어하기

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') 

: 당신은 같은 뭔가가 필요

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)) 
+0

이것은 훌륭했으며 전체 예제에 감사드립니다. 이 일을 처리하는 SQLAlchemy 구조화 된 방법이 있다는 것을 알고 있었지만 예제를 찾을 수 없었습니다. 이것은 저와 함께 나아 갔고 장래에 다른 사람들을 도울 것입니다. –