2016-08-29 4 views
0

これは私の問題で重要な2つのデータベースモデルです。Flask SQL Alchemyでone to many/many to many関係をクエリするには?

私は、多くの関係に1を確立している(会話が複数のメッセージを持つことができます) ユーザーと会話の間に確立多くの関係に多くのもあります。

は、2つのユーザーオブジェクトを取得した後、私はそれが存在する場合は、両方のユーザーが含まれている会話を見つける必要があり、 USER1 user2のを言います。会話オブジェクトを取得した後、 current_convoと言うと、その会話のすべてのメッセージも照会する必要があります。これらの2つのクエリはどのように実行できますか?

class Conversation(db.Model): 
    __tablename__ = 'conversation' 

    id = db.Column('id', db.Integer, primary_key=True) 
    users = db.relationship("User", secondary=relationship_table) 
    messages = db.relationship("Message", backref="conversation", lazy="dynamic") 


class Message(db.Model): 
    __tablename__ = 'message' 

    id = db.Column('id', db.Integer, primary_key=True) 
    message = db.Column('message', db.String) 
    timestamp = db.Column('timestamp', db.String) 
    sender = db.Column('sender', db.String) 
    conversation_id = db.Column(db.Integer, db.ForeignKey('conversation.id')) 

class User(db.Model, UserMixin): 
    __tablename__ = 'user' 

    id = db.Column('id', db.Integer, primary_key=True) 
    username = db.Column('username', db.String(100), unique=True, index=True) 
    password = db.Column('password', db.String(100)) 
    email = db.Column('email', db.String(100), unique=True, index=True) 
    authenticated = db.Column('authenticated', db.Boolean, default=False) 
+0

2人のユーザー間で会話が1つしかないと仮定できますか?同じ2人のユーザー間で複数の会話が行われる場合はありますか? – flyingmeatball

+0

@dirnすでに会話とメッセージの間には1対多の関係があります。私はちょうどそれをクエリを書く方法を知らない。 –

+0

あなたはちょうどuser1とuser2の間で会話したいのですか、それとも他の参加者を含む会話をしたいですか? – dirn

答えて

2

これを行うにはSQLAlchemyのcontainsを使用するのが最善の方法です。

Conversation.query.filter(
    Conversation.users.contains(user1), 
    Conversation.users.contains(user2) 
) 
-1

これは純粋なSQLクエリではありませんが、ここで私はあなたがパンダを使用して求めているものを成し遂げるだろうかです。

import pandas as pd 
import sqlalchemy 
import urllib 

#setup vars and connection 
server = 'myServer' 
db = 'myDb' 

user1 = 'someId1' 
user2 = 'someId2' 

#You'll have to maybe change this a little if you aren't using a trusted connection on SQL Server 
connStr = 'DRIVER={SQL Server};SERVER=' + server + ';DATABASE=' + db + ';Trusted_Connection=yes' 
conn = sqlalchemy.create_engine(
      'mssql+pyodbc:///?odbc_connect=%s' % (urllib.quote_plus(connStr))) 

#select all conversations that have one of the users 
query = """select * from Conversation where users is in ('{0}','{1}')""".format(user1,user2) 
conv_df = pd.read_sql(query,conn) 

#unstack the users, so we can see which users are part of the same conversation 
conv_users = conv_df.set_index(['id','users']).unstack().reset_index() 

#filter conversations to those that have both users 
conv_together = conv_users[(conv_users[user1].notnull()) & (conv_users[user2].notnull())] 

conv_list = conv_together['id'].tolist() 
conv_str = "(" + ', '.join("'{0}'".format(w) for w in conv_list) +")" 

#select all messages where the conv id matches your criteria (has both users) 
query = """select * from Message where conversation_id is in {0}""".format(conv_str) 

message_df = pd.read_sql(query,conn) 

なしの試験データとの中間ステップを表示するために、その難しいので、私は実行して、QCこのコードを、うまくいけば、それはあなたの右のアイデアを提供することはできません。