抱歉,我想不出更好的通用标题了。我正在使用金字塔和sqlalchemy构建一个照片投票应用程序。完整的模式和orm在最后,但是最相关的信息是
photo
表photo_id
和user_id
的{category
带有照片类别列表的表photocategory
表链接photo
和category
表在应用程序的主要照片饲料我想显示以下顺序的照片
该应用程序还将有灵活性,显示照片从某些类别只
我现在实施的方式是。。。你知道吗
即
photos = DBSession.query(Photos).join(photocategory, Photo.id==photocategory.c.photo_id).filter(photocategory.c.category_id==__CATEGORY_ID_HERE__).all()
photos
排序即
photos = sorted(photos, key=lambda photo: len(photo.votes), reverse=True)
photos
以查看用户是否已经投票,并将照片附加到voted
或unvoted
列表/数组然而,这是如此低效,因为我必须搜索所有的照片,用户以前投票给每一张照片在photos
,所以我想知道什么是正确和有效的方式来做这件事。。。谢谢
模式
photo_table = schema.Table('photo', metadata,
schema.Column('id', types.Integer,
schema.Sequence('photo_seq_id'), primary_key=True),
schema.Column('caption', types.UnicodeText(), nullable=True),
schema.Column('timestamp', types.TIMESTAMP(), default=datetime.now()),
schema.Column('last_updated', types.TIMESTAMP(), default=datetime.now(),),
schema.Column('spam', types.Boolean, default=0),
schema.Column('trash', types.Boolean, default=0),
schema.Column('image_path', types.Unicode(255), nullable=False),
schema.Column('user_id', types.Integer, schema.ForeignKey('user.id', ondelete='CASCADE')),
mysql_engine='InnoDB'
)
category_table = schema.Table('category', metadata,
schema.Column('id', types.Integer,
schema.Sequence('category_seq_id'), primary_key=True),
schema.Column('name', types.Unicode(255), nullable=False, unique=True),
mysql_engine='InnoDB'
)
photocategory_table = schema.Table('photocategory', metadata,
schema.Column('photo_id', types.Integer, schema.ForeignKey('photo.id', ondelete='CASCADE'), primary_key=True),
schema.Column('category_id', types.Integer, schema.ForeignKey('category.id', ondelete='CASCADE'), primary_key=True),
mysql_engine='InnoDB'
)
vote_table = schema.Table('vote', metadata,
schema.Column('id', types.Integer,
schema.Sequence('vote_seq_id'), primary_key=True),
schema.Column('timestamp', types.TIMESTAMP(), default=datetime.now()),
schema.Column('upvote', types.Boolean, nullable=False),
schema.Column('photo_id', types.Integer, schema.ForeignKey('photo.id', ondelete='CASCADE')),
schema.Column('user_id', types.Integer, schema.ForeignKey('user.id', ondelete='CASCADE')),
mysql_engine='InnoDB'
)
ORM映射器
orm.mapper(Photo, photo_table, properties={
'votes': orm.relation(Vote, backref='photo', lazy='dynamic'),
'categories': orm.relation(Category, secondary=photocategory_table, backref='photos'),
})
orm.mapper(User, user_table, properties={
'photos': orm.relation(Photo, backref='owner'),
'votes': orm.relation(Vote, backref='voter', lazy='dynamic'),
})
也许使用SQL本身做这件事是个更好的主意。以下是未经测试,可能不会工作,但您可以调整它,以满足您的需要
您可以通过以下方式选择某个类别的照片
加入user和photo表以获得用户可以投票的照片列表。假设用户不能对自己的照片进行投票,那么
现在您可以将其加入到投票表和子查询中,以获取用户尚未投票的特定类别的照片
获取按投票数排序的此类照片。我们将不得不做一个左加入,因为可能有一些照片还没有人投票
注意-我为每个查询添加了一个aooption
options(lazyload('*'))
,以使关系延迟加载现在你有两张单子-
sorted_votes
按降序列出这类照片 投票顺序(没有人投票的照片0票)not_voted
其中列出了未经用户投票的此类照片请注意,用户上传的此类照片将是第一个列表的一部分
您可以在python中处理这两个列表,首先根据它们在第一个列表中的索引显示not\u voted,然后按原样显示第一个列表的其余部分
这将是一个好主意(IMO)如果你只从这些查询得到照片的ID。整个Photo对象列表可以从DB中单独获取,并保存在以Photo\ id为键的字典中。因此,在模板中,如果您知道要显示的照片id,就可以显示整个照片细节。你知道吗
最后一点注意:如果有些东西不起作用,请尝试为您正在尝试的操作编写一个普通的SQL,然后编写与SQLAlchemy等价的语句并打印该语句,以比较手工编写的SQL和SQLAlchemy生成的SQL是否相同
相关问题 更多 >
编程相关推荐