сообщения, связанные с sqlalchemy (упорядочение по общим отношениям «многие ко многим») - PullRequest
3 голосов
/ 29 апреля 2020

В моем приложении flask существует отношение "многие ко многим" между Article и Tags:

article_tags =db.Table("article_tags",
    db.Column('article_id', db.Integer, db.ForeignKey('articles.id')),
    db.Column('tag_id', db.Integer, db.ForeignKey('tags.id')))

class Article(db.Model):
    __tablename__ = 'articles'
    id = db.Column(db.Integer, primary_key=True)
    ...
    tags = db.relationship('Tags',secondary=article_tags,backref=db.backref('articles',lazy='dynamic'), lazy='dynamic')

class Tags(db.Model):
    __tablename__="tags"
    id = db.Column(db.Integer,primary_key=True,index=True)
    name = db.Column(db.String(64),unique=True,index=True)

. Учитывая конкретную c статью, мне нужно запросить все остальные статьи, сгруппированные по количество тегов в общем. Например, из следующего набора:

Article1.tags = tag1,tag2,tag3,tag4
Article2.tags = tag1,tag3,tag5
Article3.tags = tag1,tag3,tag4,tag5

Учитывая Article1, я бы хотел, чтобы запрос возвратил:

Common Tags | Article
3             Article3 
2             Article2

Результат даст справедливое приближение большинства связанных постов. Благодаря этой статье я смог выяснить запрос, который сортирует все статьи по общему количеству тегов, но мне нужно уточнить его только по общим тегам с данной статьей:

db.session.query(Article,func.count(article_tags.c.tag_id).label('tot
al')).join(article_tags).group_by(Article).order_by('total').all()

Любая помощь для хорошего запроса будет принята с благодарностью.

1 Ответ

1 голос
/ 29 апреля 2020

Я нашел запрос для этого, затем преобразовал его для использования ORM.
Он использует один подзапрос.
Я использовал ванильный SQLAlchemy и создал свои модели немного другим способом, поэтому мне будет интересно знать, если у вас возникнут какие-либо проблемы с этим.

article_id = 1

sub_stmt = db.session.query(article_tags.c.tag_id)\
                     .filter(article_tags.c.article_id==article_id)

db.session.query(Article.id,
                 func.count(article_tags.c.tag_id).label('total'),
                 func.group_concat(article_tags.c.tag_id).label('related_tags'))\
          .filter(Article.id!=article_id)\
          .filter(article_tags.c.tag_id.in_(sub_stmt))\
          .filter(article_tags.c.article_id==Article.id)\
          .group_by(Article.id)\
          .order_by(func.count(article_tags.c.tag_id).desc()).all()

Результат:

Out[179]: [(3, 3, '1,3,4'), (2, 2, '1,3')]

Я писал об этом решении здесь: https://www.mechanical-meat.com/blog/sqlalchemy-query-related-posts

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...