flask-script
pip install flask-script
使用里面的Manager进行命令,管理和使用程序
manager = Manager(app=app)
在终端的使用命令:
python app.py runserver
---->Runs the Flask development server
python app.py runserver -h 0.0.0.0 -p 5001
---->设置端口号和host
eg:自定义添加命令 @manager.command
app.py文件
from flask_script import Manager
from apps import create_app
app = create_app() # 程序启动的入口,在apps包里的init文件中
manager = Manager(app=app) # 将app命令交给manager管理
@manager.command
def init():
print('初始化')
if __name__ == '__main__':
manager.run()
# 此时终端下运行python app.py init 会输出初始化
数据库
在web应用里使用原生的SQL语句操作数据库固然能达到处理储存数据的需求,但是会存在以下三类问题:
手动编写SQL语句比较复杂耗时,并且视图函数中写大量SQL语句会降低代码的易读性。比较容易出现安全问题,如SQL注入;对于不同的DBMS,需要使用不同的Python接口库,语法各不相同,很难有标准化的代码流程;使用ORM可以很大程度上解决这些问题,在python中,ORM把底层的SQL数据实体转化成高层的Python对象。
在Flask应用ORM
安装Flask-sqlchemy:基于sqlchemy做提升
切入虚拟环境安装
pip install flask-sqlalchemy # 实现ORM映射
pip install pymysql
pip install flask-migrate # 发布命令工具
此时程序有三方
app,manager(flask-script管理) 以及 flask-migrate(发布命令) flask_sqlalchemy(db)
db 和 app 关联:db.init_app(app)
app 和 manager 关联:manager = Manager(app=app)
影响数据库的映射:migrate = Migrate(app=app,db=db)
db 和 manager 关联:manager.add_command('db',MigrateCommand) #将MigrateCommand命令交给manager管理
配置文件
# 公共环境
class Config:
DEBUG = True
# mysql+pymysql://user:password@hostip:port/databasename
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:zxy***@127.0.0.1:3306/fwbzz'
# 配置数据库的不追踪
SQLALCHEMY_TRACK_MODIFICATIONS = False
# 开发环境
class DevelopmentConfig(Config): # 继承Config
ENV = 'development'
# production环境
class ProductionConfig(Config):
ENV = 'production'
DDEBUG = False
创建一个新包ext,在里面的init文件中创建flask_sqlalchemy 映射对象
# 创建一个映射对象
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy() # 必须在后面的app/init文件中和app联系
在app下的init文件创建联系,添加
from ext import db
app.config.from_object(settings.DevelopmentConfig) # 加载配置改为类
db.init_app(app) # 将db对象和app进行关联
并在app.py文件添加两个映射
migrate = Migrate(app=app,db=db) # 影响数据库的映射
manager.add_command('db',MigrateCommand) # 对manager添加命令db,实现方式为MigrateCommand。即将MigrateCommand命令交给manager管理
此时在终端输入python app.py
会出现以下语句
positional arguments:{db,init,shell,runserver}
db Perform database migrations
init
shell Runs a Python shell inside Flask application context.
runserver Runs the Flask development server i.e. app.run()
python app.py db --help
查询用法
此时即可开始创建数据库表
在用户目录下的model创建表
class User(db.Model):
# db.Column(类型,约束) 映射表中的列
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
username = db.Column(db.String(15), nullable=False)
password = db.Column(db.String(64), nullable=False)
phone = db.Column(db.String(11), unique=True)
isdelete = db.Column(db.Boolean, default=False)
rdatetime = db.Column(db.DateTime, default=datetime.now)
def __str__(self):
return self.username
常见的数据类型:
Integer 整型
String(size) 字符串类型,务必指定大小
Text 长文本类型
DateTime 日期时间
Float 浮点类型
Boolean 布尔类型
PickleType 存储pickle类型 主要跟序列化有关
LargeBinary 存储大的二进制类型
可选的:
primary_key=True 主键
autoincrement=True 自增
nullable=False 不允许为空
unique=True 唯一
default=datetime.now 默认值 可以设置成当前系统时间或者其他的值
在app.py 中导入模型:from apps.user.model import User
在终端使用命令:
python app.py db init -----> 产生一个文件夹 migrations 只输入一次
python app.py db migrate -----> 在文件夹下的versions 产生一个版本文件,文件名就为版本号
python app.py db upgrade -----> 同步至数据库,此时打开cmd进入数据库即可看到表
python app.py db downgrade -----> 降级到上一个版本
如果需要修改数据库表,每次修改后都需要migrate以及upgrade。
配置pycharm中的database使之可视化
database --> + --> datasource --> mysql 输入用户名密码以及数据库名在url后添加?serverTimezone=GMT
,安装所需要的驱动即可
添加数据:
# 注册用户
# 1. 找到模型类并创建对象
user = User( )
# 2. 给对象的属性赋值
user.username = username
user.password = hashlib.sha256(password.encode('utf-8')).hexdigest( )
# 将密码hash,不可逆
user.phone = phone
# 添加并提交
# 3.将user对象添加到session中(类似缓存)
db.session.add(user)
# 4.提交数据
db.session.commit( )
密码加密的方法:
# 加密: md5 sha1 sha256 sha512
# 区别为密文长度不同,所以要根据方法确定数据库字段大小
import hashlib
msg = 'hello world'
md5 = hashlib.md5(msg.encode('utf-8')) # 编码
r = md5.hexdigest() # 转换为16进制
print(r) # 32 char
sha1 = hashlib.sha1(msg.encode('utf-8')).hexdigest()
print(sha1) # 40 char
sha256 = hashlib.sha256(msg.encode('utf-8')).hexdigest()
print(sha256) # 64 char
sha512 = hashlib.sha512(msg.encode('utf-8')).hexdigest()
print(sha512) # 128 char
终端使用python app.py runserver
开启程序
数据库的查询
# url:http://127.0.0.1:5000/test?username=2001121***
# 查询所有 select * from user;
users = User.query.all( ) # [<User 1>, <User 2>]
# 模型类.query.filter_by(字段名 = 值)
# select * from user where username='xxxx';
username = request.args.get('username')
user_list = User.query.filter_by(username=username)
# for i in user_list:
# print(i.username)
user = User.query.filter_by(username=username).all( ) # [<User 1>, <User 2>] 列表 后可以用切片
# select * from user where 字段=值 limit(1);
user = User.query.filter_by(username=username).first( ) # 2001121*** 对象
# 模型类.query.filter(模型名.字段名 == 值)
user = User.query.get(1) # 根据主键查询用户使用get(主键值)返回值是一个用户对象 2001121***
user = User.query.filter(User.username == '2001121***').all() # [<User 1>, <User 2>] 后可以用切片
user = User.query.filter(User.username == '20011210338').first() # 20011210338
# select * from user where username like '%z';
user = User.query.filter(User.username.endswith('8')).all( ) # [<User 1>, <User 2>]
# select * from user where username like 'z%';
user= User.query.filter(User.username.like('2%')).all( ) # [<User 1>, <User 2>]
user= User.query.filter(User.username.startswith('2')).all( ) # [<User 1>, <User 2>]
# select * from user where username like '%z%';
user= User.query.filter(User.username.contains('1')).all( ) # [<User 1>, <User 2>]
# 多条件查询
user_list = User.query.filter(or_(User.username.like('1%'), User.username.contains('4'))).all()
# select * from user where username like '1%' or username like '%4%';
# __gt__,__lt__,__ge__(>=),__le__(<=) -----> 通常应用在范围(整型,日期)也可以直接使用 > < >= <= !=
user_list = User.query.filter(and_(User.username.contains('2'), User.rdatetime.__gt__('2021-03-21 20:26:22'))).all()
user_list = User.query.filter(and_(User.username.contains('2'), User.rdatetime > '2021-03-21 20:26:22')).all()
user_list = User.query.filter(not_(User.username.contains('i'))).all()
# select * from user where age in [17,18,20,22];
user_list = User.query.filter(User.phone.in_(['12345678900','75964823657'])).all()
# 排列
user_list = User.query.filter(User.username.contains('2')).order_by(-User.rdatetime).all() # 负排列
user_list = User.query.order_by(-User.id).all() # 负排列 [<User 4>, <User 3>, <User 1>]
# limit的使用 + offset
user_list = User.query.limit(2).all() # 显示前两个
user_list = User.query.offset(1).limit(2).all( ) # 取出前一个后显示前两个
数据库删除
# 获取id
id = request.args.get('id')
# 获取该id的用户
user = User.query.get(id)
# 逻辑删除:
user.isdelete = True
# 提交
db.session.commit()
# 物理删除 从数据库中删除
user = User.query.get(id)
# 将对象放到缓存准备删除
db.session.delete(user)
# 提交删除
db.session.commit()
数据库的更新
id = request.form.get('id')
# 找用户
user = User.query.get(id)
# 改用户信息
user.phone = phone
user.username = username
# 提交
db.session.commit()
整体项目,请访问https://github.com/zxy1013/flask_base