1.前言
上篇文章说了SQLAlchemy中的外键约束,这篇文章就来说一下SQLAlchemy中的多对多关系如何去写。首先说一下什么是多对多关系,比如一篇文章,可以有多个标签,例如技术文章标签可能会写html 、JS、C#、Python 等。同时这些标签也有可能属于别的文章。这就是多对多关系。咱们先重新创建一个项目,起名db_demo4,添加一个config.py配置文件,新建一个数据库db_demo4.
create database db_demo4 charset utf8;
config.py
DIALECT = 'mysql' # 要用的什么数据库
DRIVER = 'pymysql' # 连接数据库驱动
USERNAME = 'root' # 用户名
PASSWORD = 'root' # 密码
HOST = 'localhost' # 服务器
PORT = '3306' # 端口
DATABASE = 'db_demo4' # 数据库名
SQLALCHEMY_DATABASE_URI = "{}+{}://{}:{}@{}:{}/{}?charset=utf8".format(DIALECT, DRIVER, USERNAME, PASSWORD, HOST, PORT, DATABASE)
SQLALCHEMY_TRACK_MODIFICATIONS = False
然后在app.py 中导入好SQLAlchemy。添加两个类。
class Article(db.Model):
__tablename__ = 'article'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String(100),nullable=False)
tags = db.relationship('Tag',secondary=article_tag,backref=db.backref('articles'))
class Tag(db.Model):
__tablename__ = 'tag'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(100), nullable=False)
注意其中article表中的tags = db.relationship('Tag',secondary=article_tag,backref=db.backref('articles'))
这里是设置多对多关系的关键地方,relationship在上篇文章中也用过。backref是反向引用。然后需要添加一个中间表,用来关联Article表和Tag表。代码如下,
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去创建,而是用一个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(100),nullable=False)
tags = db.relationship('Tag',secondary=article_tag,backref=db.backref('articles'))
class Tag(db.Model):
__tablename__ = 'tag'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(100), nullable=False)
db.create_all()
@app.route('/')
def hello_world():
# article1 = Article(title='aaa')
# article2 = Article(title='bbb')
#
# tag1 = Tag(name='111')
# tag2 = Tag(name='222')
#
# article1.tags.append(tag1)
# article1.tags.append(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()
article1 = Article.query.filter(Article.title=='aaa').first()
tags = article1.tags
for tag in tags:
print(tag.name)
return 'Hello World!'
if __name__ == '__main__':
app.run()
这里咱们是查询title名为aaa的这篇文章的所有标签,并打印出来,运行结果如下。

可以看到找到了标题名为aaa 的这篇文章的两个标签。
Study hard and make progress every day.
更多学习资料请关注"爱游戏爱编程"。
爱游戏爱编程.jpg
网友评论