Используя декларативный синтаксис, как определить отношение, представляющее последний объект в коллекции «многие к одному»? - PullRequest
1 голос
/ 23 сентября 2011

Я использую декларативный синтаксис SQLAlchemy, и я хотел бы указать отношение, которое обеспечивает самый последний (максимальный первичный идентификатор) элемент в коллекции.Я нашел этот пост: Как определить отношение SQLAlchemy, представляющее самый последний объект в коллекции? , но мне сложно использовать этот шаблон, создавая подзапрос, используя только декларативный.Любые указатели или помощь будет принята с благодарностью!

Общая идея:

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base(bind=engine, metadata=metadata)

from sqlalchemy import *
from sqlalchemy.orm import *

class NewsPaper(Base):
    __tablename__ = "newspapers"
    id = Column(Integer, nullable=False, primary_key=True)
    name = Column(String(255))
    latest_article = relationship("Article",
                                primaryjoin="(Article.newspaper_id==NewsPaper.id) &"
                                               "(Article.id==SUBQUERY_FOR_LATEST_ID)")
    def __repr__(self):
        return '''<name={0}>'''.format(self.name)


class Article(Base):
    __tablename__ = "articles"
    id = Column(Integer, nullable=False, primary_key=True)
    title = Column(String(255))
    newspaper_id =  Column(Integer, ForeignKey('newspapers.id'))
    newspaper = relationship("NewsPaper", backref=backref('articles') )

    def __repr__(self):
        return '''<title={0}>'''.format(self.title)

1 Ответ

2 голосов
/ 23 сентября 2011

Самый простой способ - определить отношение вне класса после определения всех классов.
Удалите определение latest_article из NewsPaper и добавьте следующий код после определения class Article (взято непосредственно из ответа Майка, на который вы ссылались):

# define the relationship
t_article = Article.__table__
t_newpaper = NewsPaper.__table__
latest_c = (select([t_article.c.id]).
            where(t_article.c.newspaper_id == t_newpaper.c.id).
            order_by(t_article.c.id.desc()).
            limit(1).
            correlate(t_newpaper).
            as_scalar()
            )
NewsPaper.latest_article = relationship("Article", 
                            primaryjoin=and_(
                                t_article.c.id==latest_c,
                                t_article.c.newspaper_id==t_newpaper.c.id,
                            ),
                            uselist=False
                           )

Одно замечание: связь работает непосредственно с базой данных, и поэтому не будет включать в себя те экземпляры Article, которые еще не зафиксированы, но являются частью сеанса И, скорее всего, это будут те, кого вы действительно хотите. Так что будьте осторожны с этим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...