Flask-SQLAlchemy的基本概念
- 什么是Flask-SQLAlchemy?
- Flask-SQLAlchemy 是一个 Flask 扩展,简化了在 Flask 程序中使用 SQLAlchemy 的操作。
- SQLAlchemy 是一个很强大的关系型数据库框架,支持多种数据库后台。
- SQLAlchemy 提供了高层 ORM,也提供了使用数据库原生 SQL 的低层功能。
- 如何安装Flask-SQLAlchemy?
- pip install flask-sqlalchemy
- 如何配置数据库?
from flask_sqlalchemy import SQLAlchemy
basedir = os.path.abspath(os.path.dirname(__file__))
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'data.sqlite')
# sqlchemy将会追踪对象的修改并且发送信号
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
- 如何解决连接mysql数据库时的报错
import pymysql
pymysql.install_as_MySQLdb()
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:redhat@localhost/UserTest'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# 实例化对象
db = SQLAlchemy(app)
- 如何定义模型?模型这个术语表示程序使用的持久化实体。
- 模型列类型: 常用sql列属性
- 定义数据库模型:
class User(db.Model):
# 默认情况下表名为类的名称, 如果想要重新设置表名, __tablename__
# 类变量 __tablename__ 定义在数据库中使用的表名.
__tablename__ = "用户信息"
# db.Column 类构造函数的第一个参数是数据库列和模型属性的类型。
# db.Column 中其余的参数指定属性的配置选项。
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(30), unique=True, nullable=Flase) # unique=True用户名不能重复
password = db.Column(db.String(20), nullable=Flase)
email = db.Column(db.String(20), unique=True)
数据表的创建删除及数据的增删改查
首先创建一个数据库UserTest;然后连接数据库,删除并创建数据表及对数据进行增删改查操作:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
# **********************1. python3中MySQLdb报错解决方法********************
import pymysql
pymysql.install_as_MySQLdb()
app = Flask(__name__)
# **************************2. 数据库的配置与实例化****************************
# 对数据库操作(mysql, redis)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:redhat@localhost/UserTest'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# 实例化对象
db = SQLAlchemy(app)
# ******************************3. 定义数据库模型********************************
# user ==== (id, username, password, email)
class User(db.Model):
# 默认情况下表名为类的名称,如果想要重新设置表名,__tablename__
__tablename__ = "用户信息"
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(30), unique=True, index=True, nullable=False) # unique=True用户名不能重复
password = db.Column(db.String(20), nullable=False)
email = db.Column(db.String(20), unique=True, index=True)
# 设置默认值,位当前用户的创建时间
add_time = db.Column(db.DateTime, default=datetime.now() )
if __name__ == '__main__':
# 每次实验之前删除上次实验的数据表
# 删除所有的表
db.drop_all()
# 创建所有的表
db.create_all()
# 插入数据(insert)
u1 = User(username="粉条", password="westos", email="fentiao@qq.com")
u2 = User(username="粉丝", password="westos", email="fensi@qq.com")
db.session.add(u1)
db.session.add(u2)
db.session.commit()
# 删除数据(delete)
delete_user = User.query.filter_by(username="粉条").first()
db.session.delete(delete_user)
db.session.commit()
# 更新数据(update)
update_user = User.query.filter_by(username="粉丝").first()
print(update_user.email)
print("正在更新邮箱地址.......")
update_user.email = 'fensiupdate@qq.com'
db.session.add(update_user)
db.session.commit()
print(update_user.email)
# 查看数据(select)
users = User.query.all()
print(users)
关联数据库
from datetime import datetime
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import desc, func
import pymysql
pymysql.install_as_MySQLdb()
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:redhat@localhost/UserTest'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
# 用户和角色是什么关系?
# 一对多: 角色是一,用户是多,外键写在多的一端
class Role(db.Model):
__tablename__ = "用户角色"
# id号递增 autoincrement=True
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(20))
# 反向引用,Role表中有属性users,User类中有role这个属性
users = db.relationship('User', backref='role')
def __repr__(self):
return "<Role %s>" % (self.name)
class User(db.Model):
__tablename__ = "网站用户"
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(30), unique=True, index=True, nullable=False) # unique=True用户名不能重复
password = db.Column(db.String(20), nullable=False)
email = db.Column(db.String(20), unique=True, index=True)
# 设置默认值,为当前用户的创建时间
add_time = db.Column(db.DateTime, default=datetime.now())
# 重要:用户角色id不能随便设置,需要从Role中查询(外键关联)
role_id = db.Column(db.Integer, db.ForeignKey('用户角色.id'))
# 定义了__repr()__ 方法,返回一个具有可读性的字符串表示模型,可在调试和测试时使用。
def __repr__(self):
return "<User %s>" % (self.username)
if __name__ == '__main__':
db.drop_all()
db.create_all()
# ***********************1. 添加数据***********************
# 1). 添加角色
role1 = Role(name="普通用户")
role2 = Role(name="会员")
role3 = Role(name="管理员")
db.session.add_all([role1, role2, role3])
db.session.commit()
# 2). 添加用户
user1 = User(username="westos1", password="westos1", email="westos1@qq.com", role_id=1)
db.session.add(user1)
db.session.commit()
# **********************2. 查看数据信息***********************
print(User.query.all())
print(Role.query.all())
# 批量添加用户:100个普通用户,50个VIP用户,10个管理员
# **********************批量添加数据***********************
for item in range(100):
user = User(
username="fentiao%s" % (item),
password="fentiao",
email="fentiao%s" % (item),
role_id=1
)
db.session.add(user)
for item in range(50):
user = User(
username="vip%s" % (item),
password="vip",
email="vip%s" % (item),
role_id=2
)
db.session.add(user)
for item in range(10):
user = User(
username="admin%s" % (item),
password="admin",
email="admin%s" % (item),
role_id=3
)
db.session.add(user)
# 将批量添加的用户提交到数据库中
db.session.commit()
# **********************查看数据信息:过滤器查询**********************
# filter_by过滤器的使用: 获取所有的普通用户、vip用户
common_users = User.query.filter_by(role_id='1').all()
print(common_users)
vip_users = User.query.filter_by(role_id='2').all()
print(vip_users)
# '获取所有的普通用户'转化成的sql语句并查看
print(User.query.filter_by(role_id='1'))
print(User.query)
# filter过滤器的使用(更偏向于SQL语句,不建议使用)
common_users = User.query.filter(User.role_id == 1).all()
print(common_users)
# limit过滤器: 只显示返回结果的前几条数据
common_users_limit = User.query.filter(User.role_id == 1).limit(5).all()
print(common_users_limit)
# offset过滤器: 偏移显示
common_users_offset = User.query.filter(User.role_id == 1).offset(2).limit(3).all()
print(common_users_offset)
# order_by排序过滤器: 默认是升序的,如果要降序 ----> desc(属性名)
# 升序
common_users_order = User.query.order_by(User.role_id).all()
print(common_users_order)
# 降序
common_users_desc_order = User.query.order_by(desc(User.role_id)).all()
print(common_users_desc_order)
# group_by过滤器: 分组统计
users_analysis = User.query.add_columns(func.count(User.role_id)).group_by(User.role_id).all()
print(users_analysis)
查询过滤器总结:
# get方法
print(User.query.get(1))
# print(User.query.get_or_404(1000))
# count方法
print(User.query.filter_by(role_id=1).count())
print(User.query.filter_by(role_id=2).count())
print(User.query.filter_by(role_id=3).count())
分页对象(paginate)
# page=2: 要显示第2页的数据, per_page=5: 每页显示数据的条数
usersPageObj = User.query.paginate(page=2, per_page=5)
# *********************分页对象的属性*********************
print("当前页面的记录数:", usersPageObj.items)
print("分页查询的源sql语句:", usersPageObj.query)
print("当前显示的页数:", usersPageObj.page)
print("上一页的页数:", usersPageObj.prev_num)
print("下一页的页数:", usersPageObj.next_num)
print("是否包含上一页:", usersPageObj.has_prev)
print("是否包含下一页:", usersPageObj.has_next)
print("总页数:", usersPageObj.pages)
print("每页记录的数量:", usersPageObj.per_page)
print("记录总数:", usersPageObj.total)
# *********************分页对象的方法*********************
print("页码显示:", list(usersPageObj.iter_pages()))
print("上一页的数据:", usersPageObj.prev().items)
print("下一页的数据:", usersPageObj.next().items)
Flask-Script的基本概念
1.什么是Flask-Script?
Flask-Script用来生成shell命令,为在Flask里编写额外的脚本提供了支持。
这包括运行一个开发服务器,一个定制的Python命令行,用于执行初始化数据库、
定时任务和其他属于web应用之外的命令行任务的脚本。
Flask-Script和Flask本身的工作方式类似,只需要定义和添加能从命令行中被
Manager实例调用的命令即可。
- 为什么使用Flask-Script?
Flask的开发Web服务器支持很多启动设置选项,但只能在脚本中作为参数传给
app.run()函数。这种方式很不方便,传递设置选项的理想方式是使用命令行参数。
Flask-Scrip就是这么一个Flask扩展,为Flask程序添加一个命令行解析器。
Flask-Script自带了一组常用选项,而且还支持自定义命令。
- 如何安装Flask-Script?
pip install flask_script
- 如何配置Flask-Script?
创建一个Python模块运行你的命令脚本。可以任意起名,例如 manage.py。
无需把所有的命令都放在同一个文件里。例如,在一个大型项目中,可以把相关联的命令放在不同的文件里。
from flask_script import Manager
app = Flask(__name__)
# Manager类将追踪所有的在命令行中调用的命令和处理过程的调用运行情况
manager = Manager(app)
if __name__ == "__main__":
# 将启动Manger实例接收命令行中的命令。
manager.run()
实现功能
(2048) [root@foundation0 day36]# python manage.py
usage: manage.py [-?] {shell,runserver} ...
positional arguments:
{shell,runserver}
shell Runs a Python shell inside Flask application context.
runserver Runs the Flask development server i.e. app.run() # 运行服务器, 可以指定host和端口
1010 python manage.py runserver
1011 python manage.py runserver -h
1012 python manage.py runserver -h '0.0.0.0' -p 8089
optional arguments:
-?, --help show this help message and exit
- 添加自定义命令的3种方式:
网站参考: https://flask-script.readthedocs.io/en/latest/
定义Command的子类
使用command装饰器
使用option装饰器
# 1. 方法一: 类的继承
class AddUser(Command):
"""添加用户"""
def run(self):
u = User(username="fentiao90009", password="fentiao", email="fentiao@qq.com")
db.session.add(u)
db.session.commit()
return "正在添加用户%s........" % (u.username)
# 添加类到命令中, 让manger进行管理
database_manager.add_command('adduser', AddUser)
# 2. 通过装饰器@database_manager.command
@database_manager.command
def deleteUser():
"""删除用户"""
u = User.query.filter_by(username='fentiao90009').first()
if u:
db.session.delete(u)
db.session.commit()
return "删除用户%s成功....." % (u.username)
else:
return "删除用户失败:"
# 3). option装饰器, 可以指定参数
@database_manager.option('-u', '--username', help="指定用户名")
@database_manager.option('-p', '--password', help="指定密码")
def add_user(username, password):
"""添加用户,指定用户名和密码"""
if username and password:
u = User(username=username, password=password)
db.session.add(u)
db.session.commit()
return "添加用户%s成功" %(u.username)
else:
return "请指定用户名和密码"
Flask-Migrate的基本概念
- 什么是Flask-Migrate?
Flask-Migrate是一个为Flask应用处理SQLAlchemy数据库迁移的扩展,使得可以通过Flask的命令行接口或者Flask-Scripts对数据库进行操作。
- 如何安装Flask-Migrate?
pip install flask-migrate
- 如何配置?
app = Flask(__name__)
app.config.from_envvar('config.py')
db = SQLAlchemy(app)
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
- 如何使用?
1). 创建迁移仓库(migrations目录)
python script.py db init
2). 读取类的内容, 生成版本文件, 并没有真正在数据库中添加或删除;
python script.py db migrate -m “版本名后缀”
3). 在数据库中增删改, 也就是将迁移应用于数据库;
python script.py db upgrade
4). 检测是否成功?
mysql -uroot -pwestos
5). 去查看改变的历史状态;
python script.py db history
6). 返回指定的版本状态;降级数据库,不指定版本则是最老版本
python script.py db downgrade base
7). 显示当前版本
python data_migrate.py db current
8). 升级版本,不指定版本为最新版本
python data_migrate.py db upgrade 版本号
7). 帮助,查找所有命令
python data_migrate.py db --help