我有下面的数据模型。我如何按日期降序对评论顺序进行分页
user.comments.order_by(Comment.date.desc())[0:100];
我是否可以提出,但association_proxy没有order_by?我要做的是返回用户的评论列表,并按最新评论排序。我的代码中有很多区域会使用类似的模式。
我的数据模型示例:
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship, backref
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String(64))
# association proxy of "user_comments" collection
# to "comment" attribute
comments = association_proxy('user_comments', 'comment')
def __init__(self, name):
self.name = name
class UserComment(Base):
__tablename__ = 'user_comment'
user_id = Column(Integer, ForeignKey('user.id'), primary_key=True)
comment_id = Column(Integer, ForeignKey('comment.id'), primary_key=True)
# bidirectional attribute/collection of "user"/"user_comments"
user = relationship(User,
backref=backref("user_comments",
cascade="all, delete-orphan")
)
# reference to the "Comment" object
comment = relationship("Comment")
def __init__(self, comment=None, user=None):
self.user = user
self.comment = comment
class Comment(Base):
__tablename__ = 'comment'
id = Column(Integer, primary_key=True)
comment = Column('comment', String(64))
date = db.Column(db.DateTime)
def __init__(self, comment):
self.comment = comment
def __repr__(self):
return 'Comment(%s)' % repr(self.comment)
答案 0 :(得分:3)
在SQLAlchemy中,关系绑定属性通常没有您所描述的“order_by()”方法。在SQLAlchemy中,“order_by()”是一种产生SELECT语句的方法,如session.query()和select()。像“user.comments.order_by()”之类的东西有意义的一种情况是,如果你正在使用所谓的“动态”关系,这是一种特殊策略,其中附加到实例的集合实际上是一个查询()对象。在上面,我没有看到任何“动态”的使用,因此不适用。
在上面的示例中,如果您已经加载了“用户”对象,并且您说“user.comments”,那么最好只加载一次评论然后将它们保存在内存中。所以你需要在这里的关系上使用ORDER BY,但是你正在使用关联对象模式,这使得执行它变得更加困难。我上面没有看到您需要使用关联对象模式,因为您没有任何其他属性,所以如果是这样的话我会丢失关联映射并将order_by放在关系上,也就是说,替换UserComment类如下:
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String(64))
comments = relationship("Comment",
secondary=Table('user_comment', Base.metadata,
Column('user_id', ForeignKey('user.id'), primary_key=True),
Column('comment_id', ForeignKey('comment.id'), primary_key=True)
),
order_by="Comment.date.desc()"
)
def __init__(self, name):
self.name = name
现在,如果你真的有理由明确地映射UserComment,你仍然可以获得你想要的效果,如果你建立一个跳过UserComment映射的关系,如果你把“动态”放在它上面你想要的确切语法工作:
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String(64))
comments = relationship("Comment",
secondary="user_comment",
lazy="dynamic", viewonly=True)
def __init__(self, name, **kw):
super(User, self).__init__(**kw)
self.name = name
class UserComment(Base):
__tablename__ = 'user_comment'
user_id = Column(Integer, ForeignKey('user.id'), primary_key=True)
comment_id = Column(Integer, ForeignKey('comment.id'), primary_key=True)
user = relationship(User,
backref=backref("user_comments",
cascade="all, delete-orphan")
)
comment = relationship("Comment")
def __init__(self, comment=None, user=None):
self.user = user
self.comment = comment
class Comment(Base):
__tablename__ = 'comment'
id = Column(Integer, primary_key=True)
comment = Column('comment', String(64))
date = Column(DateTime)
def __init__(self, comment):
self.comment = comment
def __repr__(self):
return 'Comment(%s)' % repr(self.comment)
e = create_engine("sqlite://", echo=True)
Base.metadata.create_all(e)
s = Session(e)
s.add_all([
User(name='u1', user_comments=[
UserComment(comment=Comment(comment='c1')),
UserComment(comment=Comment(comment='c2')),
UserComment(comment=Comment(comment='c3')),
])
])
s.commit()
u1 = s.query(User).first()
print u1.comments.order_by(Comment.date.desc()).all()
(旁注,为什么User->评论多对多?评论是否可以由多个用户拥有?这看起来很奇怪?)