Как преобразовать подзапрос SQL в sqlachemy? - PullRequest
0 голосов
/ 25 октября 2018

Как я могу преобразовать sql в sqlachemy?

Мой SQL

SELECT ev,
      min(event_time) AS first_event,
      max(event_time) AS last_event,
      min(arrival_time) AS first_arrival,
      max(arrival_time) AS last_arrival,
      count(DISTINCT(device_id)) AS device_id_count,
     (select category_value from A where category = 1 and A.ev = AAA.ev) as category_value
  FROM A as AAA
 where AAA.id <= 2 GROUP BY ev

Как я знаю, в sqlachemy была функция subquery(), но я не понимаю, как конвертировать (select category_value from A where category = 1 and A.ev = AAA.ev) в код sqlachemy

Моя попытка использовать SQL-алхимию (отформатирована для удобства чтения)

session.query(
    A.env, 
   func.min(A.event_time),
   func.max(A.event_time),
   func.min(A.arrival_time),
   func.max(A.arrival_time),
   func.count(A.device_id.distinct())).filter(A.id >=2 ).group_by(A.env)

1 Ответ

0 голосов
/ 28 октября 2018

Чтобы преобразовать select category_value from A where category = 1 and A.ev = AAA.ev в подзапрос, вы должны создать запрос точно так же, как обычно, а затем вызвать его метод .label(), чтобы вернуть скалярное значение, которое можно использовать вместо выражения столбца в вашем основном запросе.Следующий код sqlalchemy должен копировать ваш исходный SQL и выводить сгенерированный SQL на терминал при выполнении.

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, aliased
from sqlalchemy.sql.expression import func

engine = create_engine('sqlite:///:memory:', echo=True)
Base = declarative_base()

class A(Base):
    __tablename__ = "a"

    id = Column(Integer, primary_key=True)
    event_time = Column(String)
    arrival_time = Column(String)
    device_id = Column(String)
    event_time = Column(String)
    ev = Column(String)
    category = Column(Integer)
    category_value = Column(String)

Base.metadata.drop_all(engine)
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()


AAA = aliased(A, name="AAA")
category_value = session.query(A.category_value).filter(A.category == 1).filter(A.ev == AAA.ev).label("category_value")
query = session.query(
    AAA.ev, 
    func.min(AAA.event_time).label("first_event"),
    func.max(AAA.event_time).label("last_event"),
    func.min(AAA.arrival_time).label("first_arrival"),
    func.max(AAA.arrival_time).label("last_arrival"),
    func.count(AAA.device_id.distinct()).label("device_id_count"),
    category_value,
).filter(AAA.id <= 2).group_by(AAA.ev).all()
...