申し訳ありませんが、これにふさわしい一般的なタイトルが思いつきません。ピラミッドと sqlalchemy を使用して写真投票アプリを構築しています。完全なスキーマと orm は最後にありますが、最も関連性の高い情報は次のとおりです。
photo
テーブルvote
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
がすでに投票しているかどうかを確認し、写真を avoted
またはunvoted
list/arrayに追加します。
ただし、ユーザーが以前に投票したすべての写真を検索する必要があるため、これは非常に非効率的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'),
})