1.flask连接数据库的四步:

  1. 倒入第三方数据库扩展包:from flask_sqlalchemy import SQLAlchemy
  2. 配置config属性,连接数据库:

    app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:mysql@localhost/first_flask"
    app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False

  3. 创建数据库first_flask
  4. 创建操作数据库对象:db = SQLAlchemy(app)

下面直接上代码解释:

# -*- coding:utf- -*-
from flask import Flask
from flask_sqlalchemy import SQLAlchemy app = Flask(__name__)
# url的格式为:数据库的协议://用户名:密码@ip地址:端口号(默认可以不写)/数据库名
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:mysql@localhost/first_flask"
# 动态追踪数据库的修改. 性能不好. 且未来版本中会移除. 目前只是为了解决控制台的提示才写的
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 创建数据库的操作对象
db = SQLAlchemy(app) class Role(db.Model): __tablename__ = "roles"
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(),unique=True)
# 给Role类创建一个uses属性,关联users表。
# backref是反向的给User类创建一个role属性,关联roles表。这是flask特殊的属性。
users = db.relationship('User',backref="role")
# 相当于__str__方法。
def __repr__(self):
return "Role: %s %s" % (self.id,self.name) class User(db.Model):
# 给表重新定义一个名称,默认名称是类名的小写,比如该类默认的表名是user。
__tablename__ = "users"
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(),unique=True)
email = db.Column(db.String(),unique=True)
password = db.Column(db.String())
# 创建一个外键,和django不一样。flask需要指定具体的字段创建外键,不能根据类名创建外键
role_id = db.Column(db.Integer,db.ForeignKey("roles.id")) def __repr__(self):
return "User: %s %s %s %s" % (self.id,self.name,self.password,self.role_id) @app.route('/')
def hello_world():
return 'Hello World!' if __name__ == '__main__':
# 删除所有的表
db.drop_all()
# 创建表
db.create_all() ro1 = Role(name = "admin")
# 先将ro1对象添加到会话中,可以回滚。
db.session.add(ro1) ro2 = Role()
ro2.name = 'user'
db.session.add(ro2)
# 最后插入完数据一定要提交
db.session.commit() us1 = User(name='wang', email='wang@163.com', password='', role_id=ro1.id)
us2 = User(name='zhang', email='zhang@189.com', password='', role_id=ro2.id)
us3 = User(name='chen', email='chen@126.com', password='', role_id=ro2.id)
us4 = User(name='zhou', email='zhou@163.com', password='', role_id=ro1.id)
us5 = User(name='tang', email='tang@itheima.com', password='', role_id=ro2.id)
us6 = User(name='wu', email='wu@gmail.com', password='', role_id=ro2.id)
us7 = User(name='qian', email='qian@gmail.com', password='', role_id=ro1.id)
us8 = User(name='liu', email='liu@itheima.com', password='', role_id=ro1.id)
us9 = User(name='li', email='li@163.com', password='', role_id=ro2.id)
us10 = User(name='sun', email='sun@163.com', password='', role_id=ro2.id)
db.session.add_all([us1, us2, us3, us4, us5, us6, us7, us8, us9, us10])
db.session.commit()
app.run(debug=True)

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

下面插播一条bug:

当把表格创建完成,注释这两句话:

 # 删除所有的表
db.drop_all()
# 创建表
db.create_all()

然后向表格里面插入数据,此时会出现这样的错误:

sqlalchemy.exc.IntegrityError: (_mysql_exceptions.IntegrityError) (1062, "Duplicate entry 'admin' for key 'name'") [SQL: u'INSERT INTO roles (name) VALUES (%s)'] [parameters: ('admin',)]

查了网上的好多资料说把字段的约束unique=True去掉就好了,但是根本原因不在这。

原因就是因为app.run(debug=True)。开启debug模式之后,当我们修改代码的时候,比如将删除表和创建表这两句话注释,然后打开插入数据的注释。这个过程debug模式默认就已经把程序运行一遍了。此时数据库就已经有了数据,当我们再次手动执行的时候,又往数据库中插入了一条数据,这时候就会报错。因为字段的约束是唯一性的unique,所以解决的办法有两种:

第一种:就是不要将删除表和创建表这两句话注释,每次执行都要带着这两个句话。无论是debug模式自动执行还是我们手动执行程序,都会先删除表然后再创建表,所以执行多少次都不怕。

第二种:关闭debug模式。就是这样app.run()

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2.数据库的增删改查:

1.以下的方法都是返回一个新的查询,需要配合执行器使用。

filter(): 过滤,功能比较强大。
filter_by():过滤,用在一些比较简单的过滤场景。

order_by():排序。默认是升序,降序需要导包:from sqlalchemy import * 。然后引入desc方法。比如order_by(desc("email")).按照邮箱字母的降序排序。

group_by():分组。

2.以下都是一些常用的执行器:配合上面的过滤器使用。

get():获得id等于几的函数。比如:查询id=1的对象。get(1)。切记:括号里没有“id=”,直接传入id的数值就ok。因为该函数的功能就是查询主键等于几的对象。

all():查询所有的数据。

first():查询第一个数据。

count():返回查询结果的数量。

paginate():分页查询,返回一个分页对象。paginate(参数1,参数2,参数3)

参数1:当前是第几页,参数2:每页显示几条记录,参数3:是否要返回错误。

返回的分页对象有三个属性:items:获得查询的结果,pages:获得一共有多少页,page:获得当前页。

3.常用的逻辑符:

需要倒入包才能用的有:from sqlalchemy import *

not_  and_  or_   还有上面说的排序desc。

常用的内置的有:in_      表示某个字段在什么范围之中。

4.其他关系的一些数据库查询:

endswith():以什么结尾。

startswith():以什么开头。

contains():包含

5.下面体会一下上面的这些用法:

1. 查询所有用户数据
User.query.all()
2. 查询有多少个用户
User.query.count()
3. 查询第1个用户
User.query.first() 4. 查询id为4的用户[3种方式]
User.query.get(4)
User.query.filter_by(id=4).first()    
User.query.filter(User.id==4).first() filter:(类名.属性名==)
filter_by:(属性名=) filter_by: 用于查询简单的列名,不支持比较运算符
filter比filter_by的功能更强大,支持比较运算符,支持or_、in_等语法。 5. 查询名字结尾字符为g的所有数据[开始/包含]
User.query.filter(User.name.endswith('g')).all()
User.query.filter(User.name.contains('g')).all() 6. 查询名字不等于wang的所有数据[2种方式]
from sqlalchemy import not_
注意了啊:逻辑查询的格式:逻辑符_(类属性其他的一些判断)
User.query.filter(not_(User.name=='wang')).all() User.query.filter(User.name!='wang').all() 7. 查询名字和邮箱都以 li 开头的所有数据[2种方式]
from sqlalchemy import and_
User.query.filter(and_(User.name.startswith('li'), User.email.startswith('li'))).all() User.query.filter(User.name.startswith('li'), User.email.startswith('li')).all() 8. 查询password是 `123456` 或者 `email` 以 `itheima.com` 结尾的所有数据
from sqlalchemy import or_
User.query.filter(or_(User.password=='', User.email.endswith('itheima.com'))).all() 9. 查询id为 [1, 3, 5, 7, 9] 的用户列表
User.query.filter(User.id.in_([1, 3, 5, 7, 9])).all() 10. 查询name为liu的角色数据
关系引用
User.query.filter_by(name='liu').first().role.name 11. 查询所有用户数据,并以邮箱排序
排序
User.query.order_by('email').all() 默认升序
User.query.order_by(desc('email')).all() 降序
12. 查询第2页的数据, 每页只显示3条数据
help(User.query.paginate)
三个参数: 1. 当前要查询的页数 2. 每页的数量 3. 是否要返回错误 pages = User.query.paginate(2, 3, False)
pages.items # 获取查询的结果
pages.pages # 总页数
pages.page # 当前页数

3.使用第三方扩展框架迁移数据库文件。

使用框架需要配置的代码如下:

# -*- coding:utf- -*-
from flask import Flask
from flask_sqlalchemy import SQLAlchemy # 操作数据库的扩展包
from flask_script import Manager # 用命令操作的扩展包
from flask_migrate import Migrate,MigrateCommand # 操作数据库迁移文件的扩展包 app = Flask(__name__)
app.debug = True
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:mysql@localhost/second_flask"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False db = SQLAlchemy(app)
manager = Manager(app)
# 创建迁移对象
migrate = Migrate(app,db)
# 将迁移文件的命令添加到‘db’中
manager.add_command('db',MigrateCommand) class Role(db.Model):
__tablename__ = "table_roles"
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(),unique=True)
info = db.Column(db.String())
Users = db.relationship("User",backref='role') class User(db.Model):
__tablename__ = "table_users"
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(),unique=True)
info = db.Column(db.String())
role_id = db.Column(db.Integer,db.ForeignKey("table_roles.id")) @app.route('/')
def hello_world():
return 'Hello World!' if __name__ == '__main__': manager.run()

使用迁移命令如下:

比如上面的代码所在的文件名称为database.py。

1.python database.py db init    生成管理迁移文件的migrations目录

2.python database.py db migrate -m "注释"   在migrations/versions中生成一个文件,该文件记录数据表的创建和更新的不同版本的代码。

3.python database.py db upgrade  在数据库中生成对应的表格。

4.当需要改表格的时候,改完先执行第二步,然后再执行第三步。

5.需要修改数据表的版本号的时候需要做的操作如下:

python database.py db upgrade 版本号  向上修改版本号

python database.py db downgrade 版本号   向下修改版本号

可能用到的其他的语句:

python database.py db history    查看历史版本号

python database.py db current   查看当前版本号

python框架之Flask基础篇(二)-------- 数据库的操作的更多相关文章

  1. python框架之Flask基础篇(一)

    一.第一个hello world程序 # coding=utf-8 from flask import Flask app = Flask(__name__) @app.route('/') def ...

  2. python框架之Flask基础篇(三)-------- 模版的操作

    1.flask特有的变量和函数: 变量:g.session.request.config 函数:url_for().get_flashed_messages()这个函数注意了啊,记住这是个函数,别忘了 ...

  3. python框架之Flask基础篇(四)-------- 其他操作

    1.蓝图 要用蓝图管理项目,需要导入的包是:from flask import Buleprint 具体大致分为三步: 1.先在子模块中导入蓝图包,然后再创建蓝图对象. 2.然后将子模块中的视图函数存 ...

  4. Python学习笔记之基础篇(-)python介绍与安装

    Python学习笔记之基础篇(-)初识python Python的理念:崇尚优美.清晰.简单,是一个优秀并广泛使用的语言. python的历史: 1989年,为了打发圣诞节假期,作者Guido开始写P ...

  5. Farseer.net轻量级ORM开源框架 V1.x 入门篇:数据库上下文

    导航 目   录:Farseer.net轻量级ORM开源框架 目录 上一篇:Farseer.net轻量级ORM开源框架 V1.x 入门篇:数据库配置文件 下一篇:Farseer.net轻量级ORM开源 ...

  6. Farseer.net轻量级ORM开源框架 V1.x 入门篇:数据库配置文件

    导航 目   录:Farseer.net轻量级ORM开源框架 目录 上一篇:Farseer.net轻量级ORM开源框架 V1.x 入门篇:新版本说明 下一篇:Farseer.net轻量级ORM开源框架 ...

  7. php基础篇-二维数组排序 array_multisort

    原文:php基础篇-二维数组排序 array_multisort 对2维数组或者多维数组排序是常见的问题,在php中我们有个专门的多维数组排序函数,下面简单介绍下: array_multisort(a ...

  8. 智普教育Python视频教程之入门基础篇,python笔记

    智普教育Python视频教程之入门基础篇,python笔记 print id()内存地址 type()变量类型 windows命令行下edit命令 python数据类型不需要指定类型 定义hostna ...

  9. Python(三)基础篇之「模块&面向对象编程」

    [笔记]Python(三)基础篇之「模块&面向对象编程」 2016-12-07 ZOE    编程之魅  Python Notes: ★ 如果你是第一次阅读,推荐先浏览:[重要公告]文章更新. ...

随机推荐

  1. springboot学习-jdbc操作数据库--yml注意事项--controller接受参数以及参数校验--异常统一管理以及aop的使用---整合mybatis---swagger2构建api文档---jpa访问数据库及page进行分页---整合redis---定时任务

    springboot学习-jdbc操作数据库--yml注意事项--controller接受参数以及参数校验-- 异常统一管理以及aop的使用---整合mybatis---swagger2构建api文档 ...

  2. xcode5修改APP名字

    bundle display name 配置文件里面设置, 这个指的是显示在icon下面的名字.application name在itunes connect上改, 是指显示在app store上的名 ...

  3. Ubuntu 16.04安装GIMP替代PS

    GIMP虽然不能完全替代PS,但是也能弥补一下. 系统默认源中已经包含了GIMP,不需要使用PPA这些. 安装: sudo apt-get install gimp 启动: 通过Dash搜索GIMP即 ...

  4. Node & Express: some tips

    1. 设置Express端口号: 在app.js中添加 app.set('port', process.env.PORT || 3000); 之后命令行中打入 PORT=1234 node app.j ...

  5. open redis port for remote connections

    edit /etc/redis.conf Add below line after bind 127.0.0.1, then try redis-cli -h xxx.xxx.xxx.xxx ping ...

  6. 怎样在Linux下使用Markdown进行文档工作

    怎样在Linux下使用Markdown进行文档工作 在Linux系统中,编辑markdown能够用retext工具: sudo apt-get install retext retext Releas ...

  7. UDEV SCSI Rules Configuration for ASM in Oracle Linux 5 and 6

    UDEV SCSI Rules Configuration for ASM in Oracle Linux 5 and 6 For Oracle Automatic Storage Manager ( ...

  8. C++与C的那些差异

    虽说C++是向后兼容C的,但C++与C还是存在许多差异.这里举了几个例子,也是我们很容易忽略的地方.如果你还知道其他的更多的Differences,或者发现什么错误,可以评论告诉我,大家一起学习进步. ...

  9. wepack使用

    当前使用的版本:webpack 4.5. ⚠️webpack 是需要有 node 环境的,所以在使用之前需要保证你当前安装的有 node. 安装 webpack: npm install webpac ...

  10. Java程序学习中各阶段的建议

    第一部分:对于尚未做过Java工作的同学,包括一些在校生以及刚准备转行Java的同学. 一.Java基础 首先去找一个Java的基础教程学一下,这里可以推荐一个地址,或者你也可以参照这个地址上去找相应 ...