我正在使用SQLAlchemy的声明性语法,我想指定一个提供集合中最新(max primary id)元素的关系。我发现这篇文章:How do I define a SQLAlchemy relation representing the latest object in a collection?但是我很难使用这种模式,只使用Declarative创建一个子查询。任何指针或帮助将不胜感激!
一般理念:
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)
答案 0 :(得分:2)
最简单的方法是,一旦定义了所有类,定义类之外的关系
从latest_article
中删除NewsPaper
的定义,并在class Article
定义后添加以下代码(直接取自您链接到的Mike的答案):
# 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
个实例。而且很可能他们会是你真正想要的。所以要小心。