1

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

因为我不确定,所以我为 PM 尝试了下表

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”表达式。如果这是多对多关系,则还需要“辅助连接”。

据我目前了解,这是一对多的关系,但同一个类有两个外键。这甚至是正确的方法还是我应该有两张桌子,messages_sent并且messages_received?还是别的什么?任何指向正确方向的指针都将不胜感激。

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

但是from_id-column 将是发送者的用户 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)
)
4

3 回答 3

3

I don't know if answering my own question is accepted here, but I figure it's better to have some answer rather than none.

Two foreign keys to the same class didn't work, so I will have to query the database for the users outbox. But at least the inbox can be accessed via user.inbox. Below is the working code.

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)
于 2009-08-10T17:37:20.380 回答
1

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

您应该只为消息使用一个数据库。无论如何,发送的消息将与收到的消息完全相同。我不明白你说的两个外键是什么意思(我的英语不是很好),但是“from_id”列将是发件人的用户 ID,而“to_id”将是用户 ID接收者?

一些更聪明的列是发送者和接收者的“已删除”列和接收者的“已读”列。

于 2009-08-08T19:53:54.193 回答
0

您的代码示例不完整。

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

此外,您还省略了PM该类的定义。

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

于 2009-08-08T20:32:38.670 回答