2009-08-08 4 views
1

Ich bin neu in Datenbanken und möchte wissen, wie Sie persönliche Nachrichten in einer Datenbank (mit SQLAlchemy) am besten speichern.Personal Messaging System in Datenbank

Weil ich nicht sicher war, habe ich die folgende Tabelle versucht, für 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)  
) 

und dann wird diese kartiert

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

bekomme ich folgende Fehlermeldung:

Die Join-Bedingung zwischen übergeordneten/untergeordneten Tabellen in der Beziehung User.messages_sent konnte nicht ermittelt werden. Geben Sie einen Ausdruck 'primaryjoin' an. Wenn es sich um eine Viele-zu-Viele-Beziehung handelt, wird auch 'sekundäres Verbinden' benötigt.

Von dem, was ich bisher verstehe, ist dies eine Eins-zu-viele-Beziehung, aber mit zwei Fremdschlüsseln der gleichen Klasse. Ist das überhaupt der richtige Ansatz oder soll ich zwei Tabellen haben, messages_sent und messages_received? Oder noch etwas anderes? Alle Hinweise in die richtige Richtung würden sehr geschätzt.

EDIT:
Um zu verdeutlichen, bin ich nach einem guten Datenbank-Design-Muster, um dies zu lösen. Wenn jemand mit SQLAlchemy helfen kann, wäre das großartig, aber keineswegs notwendig.

aber die from_id -column würde die Benutzer-ID des Senders, und die to_id würde die Benutzer-ID des Empfängers sein?

Genau.

Ihr Codebeispiel ist unvollständig.

Ich habe versucht, unnötigen Code in diesem Beitrag weglassen, scheint, ging ich zu weit. Hier sind die fehlenden Definitionen.

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) 
) 

Antwort

3

Ich weiß nicht, ob meine eigene Frage hier akzeptiert wird, aber ich denke, es ist besser, eine Antwort zu haben, als keine.

Zwei Fremdschlüssel der gleichen Klasse haben nicht funktioniert, so dass ich die Datenbank für den Postausgang der Benutzer abfragen muss. Aber zumindest der Posteingang kann über user.inbox erreicht werden. Unten ist der Arbeitscode.

 
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

Ich weiß nicht, wie man das Programm oder die Sprache verwendet, die Sie verwenden, aber ich kann einige Hinweise auf die Verwendung von zwei DBs vs.

Sie sollten nur eine DB für die Nachrichten verwenden. Die gesendeten Nachrichten wären genau die gleichen wie die empfangenen Nachrichten. Ich verstehe nicht, was Sie mit den zwei Fremdschlüsseln meinen (mein Englisch ist nicht sehr gut), aber die 'from_id'-Spalte wäre die Benutzer-ID des Senders und die' to_id 'wäre die Benutzer-ID von der Empfänger?

Einige weitere Spalten, die intelligent eingefügt werden sollten, sind eine 'deleted'-Spalte für Sender und Empfänger und eine' read'-Spalte für den Empfänger.

0

Ihr Codebeispiel ist unvollständig.

Sie haben keine Definition für user_table oder die User Klasse angegeben.

Außerdem haben Sie die Definition für die Klasse weggelassen.

Ohne die anderen Definitionen ist es schwer herauszufinden, was falsch ist.