Flask web开发之路八

今天写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
```

人生苦短,何不用python
原文地址:https://www.cnblogs.com/yqpy/p/8658291.html