@exfizik

Как перевести на Sqlalchemy старый код, использующий SQL через pyodbc?

Пытаюсь перевести старый код, использующий SQL через pyodbc, на Sqlalchemy. Застрял на следующем запросе:
SELECT D.ALERT_ID FROM 
TBL_ALERT_DESCRIPTION D
INNER JOIN 
TBL_ALERT_PROJECTCORR P ON P.ALERT_ID = D.ALERT_ID
INNER JOIN 
TBL_CONF_PROJECTRSSFEEDCORR PRC ON P.PROJECT_ID = PRC.PROJECT_ID
WHERE D.STATUS_ID = 1 AND D.ALERT_TYPE_ID = 5 AND PRC.RSS_LOCATION_ID = 1

Сгенерировал классы для Sqlalchemy с помощью sqlacodegen, получилось вот что:
Base = declarative_base()
metadata = Base.metadata

class TblAlertDescription(Base):
    __tablename__ = 'TBL_ALERT_DESCRIPTION'
    ALERT_ID = Column(Numeric(6, 0), primary_key=True)
    STATUS_ID = Column(ForeignKey(u'TBL_ALERT_STATUS.STATUS_ID'), nullable=False, index=True)
    alert_type_id = Column(ForeignKey(u'TBL_ALERT_TYPE.alert_type_id'), nullable=False, index=True)
    alert_type = relationship(u'TblAlertType')
    TBL_CONF_PROJECT = relationship(u'TblConfProject', secondary='TBL_ALERT_PROJECTCORR')

class TblConfProject(Base):
    __tablename__ = 'TBL_CONF_PROJECT'
    PROJECT_ID = Column(Numeric(6, 0), primary_key=True)
    DESCRIPTION = Column(String(50, u'SQL_Latin1_General_CP1_CI_AS'), nullable=False)
    TBL_CONF_RSSFEEDLOCATION = relationship(u'TblConfRssfeedlocation', secondary='TBL_CONF_PROJECTRSSFEEDCORR')

class TblConfRssfeedlocation(Base):
    __tablename__ = 'TBL_CONF_RSSFEEDLOCATION'
    RSS_LOCATION_ID = Column(Integer, primary_key=True)

Некоторые поля опущены для простоты.
Плюс для 2х таблиц классы не сгенерированы (насколько я понимаю из-за того, что это association tables). В sqlacodegen-е специальное условие, что если таблица содержит только 2 foreign keys, то для неё маппинг не создается, а просто создаётся описание таблицы:
t_TBL_ALERT_PROJECTCORR = Table(
    'TBL_ALERT_PROJECTCORR', metadata,
    Column('ALERT_ID', ForeignKey(u'TBL_ALERT_DESCRIPTION.ALERT_ID'), primary_key=True, nullable=False),
    Column('PROJECT_ID', ForeignKey(u'TBL_CONF_PROJECT.PROJECT_ID'), primary_key=True, nullable=False)
)
t_TBL_CONF_PROJECTRSSFEEDCORR = Table(
    'TBL_CONF_PROJECTRSSFEEDCORR', metadata,
    Column('PROJECT_ID', ForeignKey(u'TBL_CONF_PROJECT.PROJECT_ID'), primary_key=True, nullable=False),
    Column('RSS_LOCATION_ID', ForeignKey(u'TBL_CONF_RSSFEEDLOCATION.RSS_LOCATION_ID'), primary_key=True, nullable=False)
)

В SQL я еще более менее соображаю, но Sqlalchemy только начинаю изучать, но вот на этом моменте затык. Буду признателен за помощь.
Система такая: Python 2.7.5, Centos 6.5 64bit, Sqlalchemy 0.9.1, Pymssql 2.0.1. БД MS SQL Server 2012.
  • Вопрос задан
  • 2790 просмотров
Решения вопроса 1
@euspensky
в sqlalchemy отличная документация с кучей примеров
конкретно по составлению запросов - тут

конкретно этот запрос можно записать почти как в sql
условие для join'а D и P можно не прописывать так как есть соответсвующий relationship

D = TblAlertDescription
P = t_TBL_ALERT_PROJECTCORR
PRC = t_TBL_CONF_PROJECTRSSFEEDCORR

query = session. \
    query(D.ALERT_ID). \
    select_from(D). \
    join(P). \
    join(PRC, P.c.PROJECT_ID == PRC.c.PROJECT_ID). \
    filter(D.STATUS_ID == 1,
           D.alert_type_id == 5,
           PRC.c.RSS_LOCATION_ID == 1)

print query

->
SELECT "TBL_ALERT_DESCRIPTION"."ALERT_ID" AS "TBL_ALERT_DESCRIPTION_ALERT_ID" 
FROM "TBL_ALERT_DESCRIPTION" JOIN "TBL_ALERT_PROJECTCORR" ON "TBL_ALERT_DESCRIPTION"."ALERT_ID" = "TBL_ALERT_PROJECTCORR"."ALERT_ID" JOIN "TBL_CONF_PROJECTRSSFEEDCORR" ON "TBL_ALERT_PROJECTCORR"."PROJECT_ID" = "TBL_CONF_PROJECTRSSFEEDCORR"."PROJECT_ID" 
WHERE "TBL_ALERT_DESCRIPTION"."STATUS_ID" = ? AND "TBL_ALERT_DESCRIPTION".alert_type_id = ? AND "TBL_CONF_PROJECTRSSFEEDCORR"."RSS_LOCATION_ID" = ?
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы