Я изменил мини-пример с тем же макетом базы данных: книга связана с одним пользователем (один ко многим), и в книге много слов, и слова могут появляться в нескольких книгах (от многих ко многим).Чтобы получить все слова для всех книг, связанных с пользователем, используйте этот запрос:
Word.query.join(Word, Book.words).filter(Book.user_id==1).all()
Таким образом, чтобы перевести его на ваш пример, это будет что-то вроде:
Lead.query.join(Lead, Keyword.leads).filter(Keyword.user_id==1234).all()
Полный пример:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy, BaseQuery
app = Flask(__name__)
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
books = db.relationship('Book', backref='user')
class Book(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
words = db.relationship('Word', secondary='book_to_word_junction', lazy='subquery',
backref=db.backref('book', lazy=True))
class Word(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
keyword_identifier = db.Table(
'book_to_word_junction',
db.Column('book_id', db.Integer, db.ForeignKey('book.id')),
db.Column('word_id', db.Integer, db.ForeignKey('word.id'))
)
db.create_all()
def add_db_samples():
dummy_data = {
'user1@email.com': {
'harry potter': ['yer', 'a', 'wizard', 'herry', 'no', 'way', 'hagrid'],
'egg cookbook': ['a', 'recipe', 'for', 'scrambled', 'eggs', 'no', 'really', 'yummy', 'eggs']
},
'user2@email.com': {
'da vinci code': ['some', 'action', 'some', 'romance']
}
}
for email in dummy_data:
user = User()
for title in dummy_data[email]:
book = Book(title=title)
for word_name in dummy_data[email][title]:
word = Word.query.filter_by(name=word_name).first()
if not word:
word = Word(name=word_name)
book.words.append(word)
db.session.add(word)
db.session.commit()
user.books.append(book)
db.session.add(user)
db.session.commit()
add_db_samples()
print(Word.query.join(Word, Book.words).filter(Book.user_id==1).all())
Редактировать:
относительно вашего комментария, вы используете in_()
, как вы обычно делаете на этапе фильтрации:
Word.query.join(Word, Book.words).filter(Book.user_id.in_([1,2])).all()
Lead.query.join(Lead, Keyword.leads).filter(Keyword.user_id.in_([1, 2])).all()