Skip to main content
 首页 » 编程设计

python之sqlalchemy线程消息系统

2025年05月04日998°冷暖

我是 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 通过message_read_state_relations 与User 相关。如何在没有 message_read_state_relations 的情况下获取属于该用户的所有线程的所有消息?

或者,也许,我做错了?是设计错了吗?我是根据这个问题创建的 thread messaging system database schema design

感谢您的帮助!

请您参考如下方法:

不知道是不是最好的设计,貌似是合理的。关于您询问的查询,可以使用连接和子查询构造它们,您可能想在 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()