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'式を指定します。これが多対多の関係である場合は、「secondaryjoin」も必要です。

これまでのところ、これは1対多の関係ですが、同じクラスに対する2つの外部キーがあります。これは正しいアプローチですかmessages_sent、それとも2つのテーブルが必要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

自分の質問に答えることがここで受け入れられるかどうかはわかりませんが、答えがないよりも答えがある方が良いと思います。

同じクラスへの2つの外部キーが機能しなかったため、データベースにユーザーの送信トレイを照会する必要があります。ただし、少なくとも受信トレイにはを介してアクセスできますuser.inbox。以下は動作するコードです。

クラスPM(オブジェクト):

    def __init __(self、sender_id、receiver_id、subject、message):
        self.sender_id = sender_id
        self.receiver_id=レシーバーID
        self.subject=サブジェクト
        self.message=メッセージ
        self.sent_at = datetime.utcnow()
        self.read = False
        self.deleted_sender = False
        self.deleted_receiver = False

    def __repr __(self):
        ''%(self.from_id、self.to_id)を返します

    def markread(self):
        self.read = True

    def delete(self、deleter_id):
        deleter_id == self.sender_idの場合:
            self.deleted_sender = True
        そうしないと:
            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('メッセージ'、テキスト)、
    Column('read'、Boolean)、
    Column('deleted_sender'、ブール値)、
    Column('deleted_receiver'、ブール値)、
    Column('sent_at'、DateTime)     
)。


クラスUser(オブジェクト):

    def __init __(self、username、pwsalt、pwhash、email):
        self.username=ユーザー名
        self.pwsalt = pwsalt
        self.pwhash = pwhash
        self.email = email
        self.since = datetime.utcnow()
        self.status = 0

    def __repr __(self):
        ''%(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:'ユーザー'、
    1:'vip'、
    2:「モデレーター」、
    3:「管理者」
}


session.mapper(User、user_table、properties = {
    「受信トレイ」:relation(PM)
})
session.mapper(PM、pm_table)
于 2009-08-10T17:37:20.380 に答える
1

使用しているプログラムや言語の使い方はわかりませんが、2つのDBと1つのDBの使用に関するヒントをいくつか紹介できます。

メッセージには1つのDBのみを使用する必要があります。送信されるメッセージは、とにかく受信されるメッセージとまったく同じになります。2つの外部キーの意味がわかりません(私の英語はあまり上手ではありません)が、「from_id」列は送信者のユーザーIDになり、「to_id」はのユーザーIDになります。受信者?

含めるのが賢明なその他の列は、送信者と受信者の両方の「削除済み」列と受信者の「読み取り」列です。

于 2009-08-08T19:53:54.193 に答える
0

コードサンプルが不完全です。

user_tableまたはUserクラスの定義を省略しました。

PMまた、クラスの定義を省略しました。

他の定義がなければ、何が悪いのかを理解するのは困難です。

于 2009-08-08T20:32:38.670 に答える