3

私は次のモデルとテーブルを持っています:

chat_members = db.Table('chat_members',
    db.Column('user_id', db.Integer, db.ForeignKey('user.id')),
    db.Column('chat_id', db.Integer, db.ForeignKey('chat.id'))
)

class chat(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    start_date = db.Column(db.DateTime)
    chat_memb = db.relationship('user', secondary=chat_members, backref=db.backref('members', lazy='dynamic'))  
    chat_line = db.relationship('line', backref='chat_line', lazy='dynamic')

    def __repr__(self):
        return '<Chat %r>' % (self.id)

class user(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_email = db.Column(db.String, unique=True)
    user_password = db.Column(db.String)
    lines = db.relationship('line', backref='line_author', lazy='dynamic')

    def __repr__(self):
        return '<User %r>' % (self.user_email)

class line(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    published_date = db.Column(db.DateTime)
    chat_id = db.Column(db.Integer, db.ForeignKey('chat.id'))
    sent_by = db.Column(db.Integer, db.ForeignKey('user.id'))
    line_text = db.Column(db.String)


    def __repr__(self):
        return '<Line %r>' % (self.id)

これらすべてのモデルにデータを正常に追加しましたが、テーブルのクエリに問題があります。クエリの最終的な目標は、特定のユーザーに関連付けられているすべてのチャットを検索することです。これが私がしたことです:

first_user = user.query.get(1)
chat.query.filter(chat_members.any(chat_memb=first_user)).all()

私が得た

sqlalchemy.exc.InvalidRequestError:コレクションをオブジェクトまたはコレクションと比較できません。contains()を使用してメンバーシップをテストします。

この質問(http://stackoverflow.com/questions/12593421/sqlalchemy-and-flask-how-to-query-many-to-many-relationship)は非常に似ているように見えましたが、モデルに複製すると、AttributeError: type object 'chat' has no attribute 'members'やった後

chat.query.filter(chat.members.any(user_email='ACCEPTABLE_EMAIL')).all()

membersモデル内のbackrefと同様に、トレースバックは驚きでしchatたが、このクエリが近づいているように感じます。

私が見つけた他の関連する質問は、同じ検索に関するアドバイスを提供していないようであり、公式またはサードパーティの多対多のドキュメントでそのような質問を見つけることができませんでした。

4

1 に答える 1

12

クエリで結合を使用する必要があります。まずchat.chat_memb関係を次のように変更します。

# Change backref from 'members' to 'chats', since the backref will be pointing
# to chat class.
chat_memb = db.relationship('user', secondary=chat_members,
                            backref=db.backref('chats', lazy='dynamic'))

次に、次のクエリを使用します。

chat.query.join(user.chats).filter(user.id == 1).all()

また、Python スタイル ガイドラインに従い、クラスには大文字の名前を使用することをお勧めしChatますchat。コード内でクラスとインスタンスを混同しやすくなっています。

于 2013-01-26T09:59:53.847 に答える