数据库中的个人消息系统

时间:2009-08-08 19:37:57

标签: database-design sqlalchemy

我是数据库新手,想知道如何在数据库中最好地存储个人消息(使用SQLAlchemy)。

因为我不确定,我为PMs尝试了下表

pm_table = Table('personal_message', metadata,
     Column('id', Integer, primary_key=True, autoincrement=True),
     Column('from_id', Integer, ForeignKey('user.id')),
     Column('to_id', Integer, ForeignKey('user.id')),
     Column('message', Text),
     Column('sent_at', DateTime)     
)

然后映射

session.mapper(User, user_table, properties={
     'messages_sent': relation(PM, backref='sender'),
     'messages_received': relation(PM, backref='receiver')
})

我收到以下错误消息:

  

无法确定关系User.messages_sent上的父/子表之间的连接条件。指定'primaryjoin'表达式。如果这是多对多关系,则还需要“secondaryjoin”。

据我所知,到目前为止,这是一对多的关系,但同一个类有两个外键。这是否是正确的方法,还是应该有两个表messages_sentmessages_received?还是别的什么?任何指向正确方向的人都会非常感激。

编辑:
为了澄清,我正在使用一个好的数据库设计模式来解决这个问题。如果有人可以帮助SQLAlchemy,那将是很好的,但绝不是必要的。

  

from_id - 列是发件人的用户ID,to_id是收件人的用户ID?

完全。

  

您的代码示例不完整。

我试着在这篇文章中省略不必要的代码,似乎我走得很远。以下是缺少的定义。

class PM(object):

    def __init__(self, from_id, to_id, message):
        self.from_id = from_id
        self.to_id = to_id
        self.message = message
        self.sent_at = datetime.utcnow()

session.mapper(PM, pm_table)



class User(object):

    def __init__(self, username, pwsalt, pwhash, email):
        self.username = username
        self.pwsalt = pwsalt
        self.pwhash = pwhash
        self.email = email
        self.since = datetime.utcnow()
        self.status = 0

user_table = Table('user', metadata,
    Column('id', Integer, primary_key=True, autoincrement=True),
    Column('username', String(20)),
    Column('pwsalt', String(32)),
    Column('pwhash', String(64)),
    Column('email', String(320)),
    Column('since', DateTime),
    Column('status', SmallInteger)
)

3 个答案:

答案 0 :(得分:3)

我不知道在这里是否接受回答我自己的问题,但我认为最好有一些答案而不是答案。

同一个类的两个外键不起作用,因此我将不得不在数据库中查询用户发件箱。但至少可以通过user.inbox访问收件箱。以下是工作代码。

class PM(object):

    def __init__(self, sender_id, receiver_id, subject, message):
        self.sender_id = sender_id
        self.receiver_id = receiver_id
        self.subject = subject
        self.message = message
        self.sent_at = datetime.utcnow()
        self.read = False
        self.deleted_sender = False
        self.deleted_receiver = False

    def __repr__(self):
        return '' % (self.from_id, self.to_id)

    def markread(self):
        self.read = True

    def delete(self, deleter_id):
        if deleter_id == self.sender_id:
            self.deleted_sender = True
        else:
            self.deleted_receiver = True

pm_table = Table('personal_message', metadata,
    Column('id', Integer, primary_key=True, autoincrement=True),
    Column('sender_id', Integer),
    Column('receiver_id', Integer, ForeignKey('user.id')),
    Column('subject', Text),
    Column('message', Text),
    Column('read', Boolean),
    Column('deleted_sender', Boolean),
    Column('deleted_receiver', Boolean),
    Column('sent_at', DateTime)     
)


class User(object):

    def __init__(self, username, pwsalt, pwhash, email):
        self.username = username
        self.pwsalt = pwsalt
        self.pwhash = pwhash
        self.email = email
        self.since = datetime.utcnow()
        self.status = 0

    def __repr__(self):
        return '' % (self.id, self.username, userstatus[self.status])

user_table = Table('user', metadata,
    Column('id', Integer, primary_key=True, autoincrement=True),
    Column('username', String(20)),
    Column('pwsalt', String(32)),
    Column('pwhash', String(64)),
    Column('email', String(320)),
    Column('since', DateTime),
    Column('status', SmallInteger)
)

userstatus = {
    0: 'user',
    1: 'vip',
    2: 'moderator',
    3: 'admin'
}


session.mapper(User, user_table, properties={
    'inbox': relation(PM)
})
session.mapper(PM, pm_table)

答案 1 :(得分:1)

我不知道如何使用您正在使用的程序或语言,但我可以提供一些关于使用两个DB而不是一个DB的提示。

您应该只使用一个数据库来处理这些消息。发送的消息与收到的消息完全相同。我不明白你的两个外键是什么意思(我的英语不是很好),但'from_id'列是发件人的用户ID,'to_id'是用户ID收货人?

可以包含的更多列是发送者和接收者的“已删除”列以及接收者的“读取”列。

答案 2 :(得分:0)

您的代码示例不完整。

您已省略user_tableUser类的任何定义。

此外,您已省略PM类的定义。

没有其他定义,很难弄清楚出了什么问题。