1、环境配置
class Config(object):
#连接数据库的信息,# url的格式为:数据库的协议://用户名:密码@ip地址:端口号(默认可以不写)/数据库名
SQLALCHEMY_DATABASE_URI = “mysql+pymysql://root:123456@127.0.0.1:3306/flaskfive”
动态追踪数据库的修改.
SQLALCHEMY_TRACK_MODIFICATIONS = False
会打印原生sql语句,便于观察测试
SQLALCHEMY_ECHO = True # 会打印原生sql语句,便于观察测试
在flask项目中,Session, Cookies以及一些第三方扩展都会用到SECRET_KEY值,这是一个比较重要的配置值。
#设置秘钥
SECRET_KEY=“123456”
配置操作:
①在主app.py中导入配置文件,
import config
import pymysql
②加载配置
app.config.from_object(Config)
2、增删改查
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)
db.create_all()
@app.route('/')
def index():
#增加
article1 = Article(title = 'aaa',content = 'bbb')
db.session.add(article1)
#事务
db.session.commit()
#查
result = Article.query.filter(Article.title=='aaa').first()#返回Query 类似list
print('title:'+result.title)
print('content:' + result.content)
#改 ---- 查找、修改、提交 三步走
article1 = Article.query.filter(Article.title == 'aaa').first()
article1.title = 'new title'
db.session.commit()
#删---查找、删除、提交 三步走
article1 = Article.query.filter(Article.content == 'bbb').first()
db.session.delete(article1)
db.session.commit()
return render_template('index.html')
3、外键
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'))
db.create_all()
4、关系(一对多、一对一的情况)
使用关系型数据库,不指定关系怎么能行。定义模型中我们没有指定关系,一个用户有一个角色,一个角色可以属于多个用户,典型的一对多的关系,如何在Flask-SQLAlchemy中定义关系?
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer,primary_key=True)
username = db.Column(db.String(64),unique=True,index=True)
role_id = db.Column(db.Integer,db.ForeignKey('roles.id'))
def __repr__(self):
return '<User %r>' % self.username
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(64),unique=True)
users = db.relationship('User',backref='role')
def __repr__(self):
return '<Role %r>' % self.name
添加了两行代码:
第一行,User类中:
role_id = db.Column(db.Integer,db.ForeignKey(‘roles.id’))
这句话比较好理解,和上面普通变量差不多,就是User类中添加了一个role_id变量,数据类型db.Integer,第二个参数指定外键是哪个表中哪个id。
第二行,Role类中:
users = db.Relationship(‘User’,backref=‘role’)
这句话比较复杂,仔细读下面的话:
0.添加到Role模型中的users属性代表这个关系的面向对象视角。对于一个Role类的实例,其users属性将返回与角色相关联的用户组成的列表。
1.db.Relationship()第一个参数表明这个关系的另一端是哪个模型(类)。如果模型类尚未定义,可使用字符串形式指定。
2.db.Relationship()第二个参数backref,将向User类中添加一个role属性,从而定义反向关系。这一属性可替代role_id访问Role模型,此时获取的是模型对象,而不是外键的值。
上面的关系为一对多关系的表示,一对一怎么办?
调用db.Relationship()时需要把userlist参数设置为False。如下:
db.Relationship('User',backref='role',uselist=False)
5、关系(多对多的情况)
- 多对多的关系,要通过一个中间表进行关联。
- 中间表,不能通过
class
的方式实现,只能通过db.Table
的方式实现。 - 设置关联:
tags = db.relationship('Tag',secondary=article_tag,backref=db.backref('articles'))
需要使用一个关键字参数secondary=中间表
来进行关联。 - 访问和数据添加可以通过以下方式进行操作:
- 添加数据:
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() 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
- 添加数据:
- 中间表,不能通过