今天写Flask_SQLAlchemy的外键及其关系
### Flask-SQLAlchemy外键及其关系:
主app文件代码:
from flask import Flask from flask_sqlalchemy import SQLAlchemy import config app = Flask(__name__) app.config.from_object(config) db = SQLAlchemy(app) # #用户表 # create table users{ # id int primary key autoincrement, # username varchar(100) not null # } # #文章表 # create table article{ # id int primary key autoincrement, # title varcar(100) not null, # content text not null # author id int, # foreign key 'author_id' references 'user.id' # } class User(db.Model): __tablename__ = 'user' id = db.Column(db.Integer, primary_key=True, autoincrement=True) username = db.Column(db.String(100), nullable=False) #content = db.Column(db.Text, nullable=False) class Article(db.Model): __tablename__ = 'article' id = db.Column(db.Integer, primary_key=True, autoincrement=True) title = db.Column(db.String(100), nullable=False) content = db.Column(db.Text, nullable=False) author_id = db.Column(db.Integer,db.ForeignKey('user.id'))#注意是表名 author = db.relationship('User',backref=db.backref('articles')) db.create_all() @app.route('/') def index(): # #想要添加一篇文章,因为文章必须依赖用户而存在,所以首先添加一个用户 # user1 = User(username = 'hyq') # db.session.add(user1) # db.session.commit() # article = Article(title = 'aaa',content = 'bbb',author_id=1) # db.session.add(article) # db.session.commit() # #我要找文章标题为aaa的这个作者 article = Article.query.filter(Article.title == 'aaa').first() author_id = article.author_id user = User.query.filter(User.id == author_id).first() print("username:%s" % user.username) # article.author # author = User.query.filter(User.username=='hyq').first() # author.articles # article = Article(title='aaa',content='bbb') # article.author = User.query.filter(User.id == 1).first() # db.session.add(article) # db.session.commit() # # 我要找文章标题为aaa的这个作者 # article = Article.query.filter(Article.title == 'aaa').first() # print('username:%s' % article.author.username) # #我要找到hyq这个用户写过的所有文章 # article = Article(title = '111',content='222',author_id =1) # db.session.add(article) # db.session.commit() # user = User.query.filter(User.username == 'hyq').first() # result = user.articles # for article in result: # print('-'*10) # print(article.title) return 'index' if __name__ == '__main__': app.run(debug=True)
1. 外键:
```
class User(db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
username = db.Column(db.String(100),nullable=False)
class Article(db.Model):
__tablename__ = 'article'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String(100),nullable=False)
content = db.Column(db.Text,nullable=False)
author_id = db.Column(db.Integer,db.ForeignKey('user.id'))
author = db.relationship('User',backref=db.backref('articles'))
```
2. `author = db.relationship('User',backref=db.backref('articles'))`解释:
* 给`Article`这个模型添加一个`author`属性,可以访问这篇文章的作者的数据,像访问普通模型一样。
* `backref`是定义反向引用,可以通过`User.articles`访问这个模型所写的所有文章。
3.多对多的情况:
主app文件代码:
from flask import Flask from flask_sqlalchemy import SQLAlchemy import config app = Flask(__name__) app.config.from_object(config) db = SQLAlchemy(app) # #用户表 # create table article{ # id int primary key autoincrement, # title varchar(100) not null # } # #文章表 # create table tag{ # id int primary key autoincrement, # name varcar(100) not null, # foreign key 'author_id' references 'user.id' # } # create table article_tag( # article_id int, # tag_id int, # primary key('article_id','tag_id'), # foreign key 'article_id' reference 'article.id', # foreign key 'tag_id' reference 'tag.id' # ) 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 index(): # 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_all([article1,article2,tag1,tag2]) # db.session.commit() article1 = Article.query.filter(Article.title == 'aaa').first() tags = article1.tags for tag in tags: print(tag.name) return 'index' if __name__ == '__main__': app.run(debug=True)
3. 多对多:
* 多对多的关系,要通过一个中间表进行关联。
* 中间表,不能通过`class`的方式实现,只能通过`db.Table`的方式实现。
* 设置关联:`tags = db.relationship('Tag',secondary=article_tag,backref=db.backref('articles'))`需要使用一个关键字参数`secondary=中间表`来进行关联。
* 访问和数据添加可以通过以下方式进行操作:
- 添加数据:
```
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
```