抱歉,我想不出一个更好的通用标题。我正在使用金字塔和 sqlalchemy 构建照片投票应用程序。完整的 schema 和 orm 在最后,但最相关的信息是
photo
桌子vote
带有photo_id
和的表user_id
,其中后者标识对照片投赞成票或反对票的用户。category
包含照片类别列表的表格photocategory
表链接photo
和category
表
在应用程序的主照片提要中,我想按以下顺序显示照片
- 用户未投票的照片在他/她投票的照片之前
- 在上面的每个组中(未投票然后投票),按照片现有投票数的降序排列
该应用程序还可以灵活地仅显示特定类别的照片
我现在实施的方式是......
- 只获取所需类别的照片
IE
photos = DBSession.query(Photos).join(photocategory, Photo.id==photocategory.c.photo_id).filter(photocategory.c.category_id==__CATEGORY_ID_HERE__).all()
photos
按票数排序
IE
photos = sorted(photos, key=lambda photo: len(photo.votes), reverse=True)
- 遍历
photos
以查看用户是否已经投票,并将照片附加到 avoted
或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'),
})