簡體   English   中英

SQLAlchemy多對多查詢

[英]SQLAlchemy many-to-many query

假設我有一個博客首頁,其中包含多個帖子,每個帖子都有多個標簽(例如http://pythonhosted.org/Flask-SQLAlchemy/models.html#many-to-many-relationships中的示例,但帶有帖子頁)。 如何使用SQLAlchemy在單個查詢中檢索所有顯示的帖子的所有標簽?

我這樣做的方式是這樣(我只是好奇是否有更好的方法):

  • 運行查詢,返回該頁面的所有相關帖子。
  • 使用列表推導來獲取上述查詢中所有帖子ID的列表。
  • 運行一個查詢,獲取所有post_id所在的標簽([我剛剛制作的帖子ID的列表])

那是這樣做的方式嗎?

這當然不是 做到這一點的方法 像sqlalchemy這樣的ORM的目的是將記錄和所有關系/相關記錄表示為對象,您可以在不考慮基礎sql查詢的情況下直接對其進行處理。

您無需檢索任何內容。 您已經擁有了。 Post()對象的tags -property是(類似) Tag()對象的list

我不了解Flask-SQLAlchemy,但是自從您要求使用SQLAlchemy以來,我可以隨意發布一個 SQLAlchemy示例,該示例使用Flask示例中的模型(並且是自包含的):

#!/usr/bin/env python3
# coding: utf-8

import sqlalchemy as sqAl
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship, backref

engine = sqAl.create_engine('sqlite:///m2m.sqlite') #, echo=True)
metadata = sqAl.schema.MetaData(bind=engine)

Base = declarative_base(metadata)

tags = sqAl.Table('tags', Base.metadata,
                sqAl.Column('tag_id', sqAl.Integer, sqAl.ForeignKey('tag.id')),
                sqAl.Column('page_id', sqAl.Integer, sqAl.ForeignKey('page.id'))
)

class Page(Base):
  __tablename__ = 'page'
  id = sqAl.Column(sqAl.Integer, primary_key=True)
  content = sqAl.Column(sqAl.String)
  tags = relationship('Tag', secondary=tags,
                         backref=backref('pages', lazy='dynamic'))

class Tag(Base):
  __tablename__ = 'tag'
  id = sqAl.Column(sqAl.Integer, primary_key=True)
  label = sqAl.Column(sqAl.String)

def create_sample_data(sess):
  tag_strings = ('tag1', 'tag2', 'tag3', 'tag4')
  page_strings = ('This is page 1', 'This is page 2', 'This is page 3', 'This is page 4')
  tag_obs, page_obs = [], []
  for ts in tag_strings:
    t = Tag(label=ts)
    tag_obs.append(t)
    sess.add(t)
  for ps in page_strings:
    p = Page(content=ps)
    page_obs.append(p)
    sess.add(p)

  page_obs[0].tags.append(tag_obs[0])
  page_obs[0].tags.append(tag_obs[1])
  page_obs[1].tags.append(tag_obs[2])
  page_obs[1].tags.append(tag_obs[3])
  page_obs[2].tags.append(tag_obs[0])
  page_obs[2].tags.append(tag_obs[1])
  page_obs[2].tags.append(tag_obs[2])
  page_obs[2].tags.append(tag_obs[3])

  sess.commit()

Base.metadata.create_all(engine, checkfirst=True)

session = sessionmaker(bind=engine)()
# uncomment the next line and run it once to create some sample data
# create_sample_data(session)
pages = session.query(Page).all()

for p in pages:
  print("page '{0}', content:'{1}', tags: '{2}'".format(
    p.id, p.content, ", ".join([t.label for t in p.tags])))

是的,生活可以如此輕松...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM