我是sqlalchemy的新手。现在用Flask开发网站。我想用线程来构建消息系统。像facebook对话框一样的东西。我有以下模型,这段代码有效:
message_read_state_relations = db.Table('message_message_read_state_relations',
db.Column('user_id', db.Integer, db.ForeignKey('auth_users.id')),
db.Column('message_id', db.Integer, db.ForeignKey('messages.id')),
)
class User(db.Model):
__tablename__ = 'auth_users'
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(100))
password = db.Column(db.String(100))
messages = db.relationship('Message', backref=db.backref('user'), lazy='dynamic')
threads = association_proxy('user_thread_relations', 'thread')
class Message(db.Model):
__tablename__ = 'messages'
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.Text, default='')
thread_id = db.Column(db.Integer, db.ForeignKey('threads.id'))
user_id = db.Column(db.Integer, db.ForeignKey('auth_users.id'))
user_read_states = db.relationship('User', secondary=message_read_state_relations,
backref=db.backref('message_read_states'), lazy='joined')
class Thread(db.Model):
__tablename__ = 'threads'
id = db.Column(db.Integer, primary_key=True)
subject = db.Column(db.String(255))
messages = db.relationship('Message', backref=db.backref('thread'), lazy='dynamic')
users = association_proxy('user_thread_relations', 'user')
class UserThreadRelation(db.Model):
__tablename__ = 'user_thread_relations'
user_id = db.Column(db.Integer, db.ForeignKey('auth_users.id'), primary_key=True)
thread_id = db.Column(db.Integer, db.ForeignKey('threads.id'), primary_key=True)
is_deleted = db.Column(db.Boolean, default=False)
user = db.relationship(User, backref=db.backref('user_thread_relations'))
thread = db.relationship(Thread, backref=db.backref('user_thread_relations'))
但是我无法理解一些事情。例如,如何为用户计算所有未读消息?或者未读消息在某个线程中为用户计算?
Message
与User
通过message_read_state_relations
有关系。如何在没有message_read_state_relations
的情况下将属于所有属于该用户的线程的所有消息都收到此用户?
或者,也许,我做错了吗?设计是错的吗?我是根据这个问题thread messaging system database schema design
创建的感谢您的帮助!
答案 0 :(得分:1)
不知道它是否是最好的设计,似乎是合理的。关于您询问的查询,可以使用连接和子查询构建它们,您可能希望在SQLAlchemy文档中阅读它们。我还建议在这样的查询上熟悉纯SQL方法,因为SA试图非常接近SQL,并且理解SQL有助于极大地编写SA查询。这是一个查询的示例(获取用户的所有未读消息):
# First count all the messages.
# On a big set of data this may be very slow operation.
total_msgs = db.session.query(db.func.count(Message.id).label('cnt')).subquery()
# Then count messages read by the user.
read_msgs = db.session.query(db.func.count(Message.id).label('cnt')).\
join(User.message_read_states).filter(User.id == 1).subquery()
# Subtract read messages count from total count.
unread_count = db.session.query(total_msgs.c.cnt - read_msgs.c.cnt).scalar()
答案 1 :(得分:0)
我还试图用Flask和sqlalchemy开发一个线程化消息系统。搜索我找到了您的问题和django的github存储库(下面的链接)。我认为该模型可能非常有用。如果您仍然有兴趣(6年后),请给我留言。