多对多

  • 多对多的关系要通过中间表实现
  • 中间表不能用class定义模型进行定义,必须使用db.Table才能实现

定义多地多并添加数据

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import config

app = Flask(__name__)
app.config.from_object(config)
db = SQLAlchemy(app)

# 定义中间表
# 多列组合主键
article_tag = db.Table('article_tag',
                       db.Column('article_id', db.Integer, db.ForeignKey('article.id'), primary_key=True),
                       db.Column('tag_id', db.Integer, db.ForeignKey('tag.id'), primary_key=True)
                       )

class Article(db.Model):
    __tablename__ = 'article'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    title = db.Column(db.String(30), nullable=False)
    # 定义关系
    # secondary参数是用来指定中间表的名字
    # backref参数是用来通过Tag(对象).articles查找所对应tag的文章
    tags = db.relationship('Tag', secondary=article_tag, backref=db.backref('articles'))

class Tag(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(30), nullable=False)

db.create_all()

@app.route('/')
def index():
    article1 = Article(title='a')
    article2 = Article(title='b')

    tag1 = Tag(name='t_a')
    tag2 = Tag(name='t_b')

    # 中间表添加数据
    # 将article1和tag1关系插入中间表
    article1.tags.append(tag1)
    # 将article1和tag2关系插入中间表
    article1.tags.append(tag2)

    # 将article2和tag1关系插入中间表
    # 将article2和tag2关系插入中间表
    article2.tags.append(tag1)
    article2.tags.append(tag2)

    db.session.add(article1)
    db.session.add(article2)

    db.session.add(tag1)
    db.session.add(tag2)

    db.session.commit()
    return 'Index.'

if __name__ == '__main__':
    app.run()

查询

@app.route('/')
def index():
    # 获取article1数据对象
    article1 = Article.query.filter(Article.title == 'b').first()
    # 获取article1关联的所有tags
    tags = article1.tags
    # 打印article1文章标题
    print('Article Title: {}'.format(article1.title))
    # 循环打印article1所有关联tag
    for t in tags:
        print('Tag: {}'.format(t.name))
    return 'Index.'

if __name__ == '__main__':
    app.run()

results matching ""

    No results matching ""