繁体   English   中英

如何在Flask SQL Alchemy中查询一对多/多对多关系?

[英]How to query a one to many/many to many relationship in Flask SQL Alchemy?

这是两个对我的问题很重要的数据库模型。

我已经建立了一对多关系(一个会话可以有多个消息)在用户和会话之间也建立了多对多关系。

and , I need to find the conversation that contains both users, if it exists. 在获得两个User对象(例如 ,我需要找到包含两个用户的对话(如果存在)。 , I also need to query all the messages in that conversation. 获得对话对象(例如 ,我还需要查询该对话中的所有消息。 如何完成这两个查询?

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)

我知道做到这一点的最好方法是使用SQLAlchemy的contains

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

这不是一个纯SQL查询,但是这就是我如何使用Pandas完成您所要求的。

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)

它很难显示没有测试数据的中间步骤,因此我无法运行和质量控制此代码,但希望它能为您提供正确的想法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM