热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

day054Flask_数据库,其他

今天的主要内容有:数据库迁移;邮件扩展,蓝图,单元测试以及RESTful。数据库迁移在命令行使用Flask-Migrat

今天的主要内容有:数据库迁移;邮件扩展,蓝图,单元测试以及RESTful。


数据库迁移


  • 在命令行使用Flask-Migrate包中的命令对数据库进行增删改的操作
  • 需要先在虚拟环境中安装Flask-Migigrate

    pip install flask-migrate

  • 需要使用flask-migrate中的Migrate类以及MigrateCommand类,前者负责关联app和数据库实例,后者包含了一些执行命令

  • 为什么要使用flask-migrate迁移数据库操作

    • 之前的操作是先用drop_all()将数据库清空,再用create_all()更新新的数据到数据库,这样操作是危险的,且没有记录。在实际工作中,大多数是更新数据库,但是不会删除数据
    • 可以保存每一次操作记录,像git一样记录每一次迁移信息
    • 可以返回之前的版本,也可以从旧的版本升级到新的版本,注意从旧版本升级到新的版本数据可能会丢失,所以尽量只执行更新数据库命令(db upgrade)

迁移步骤


  • 配置阶段

    1. 从flask_migrate包中导入Migrate,MigrateCommand

    from flask_migrate import Migrate,MigrateCommand

    1. 将flask的实例和qlalchemy数据库实例用Migrate()关联起来

    migrate = Migrate(app,db)

    1. 在flask_Script中添加一个db命令

    manager.add_command('db',MigrateCommand)

  • 执行阶段

    1. 初始化化Migrations文件夹

    python database.py db init

    1. 创建迁移文件

    python database.py db migrate -m 'initial migration'

    1. 执行迁移

    python database.py db upgrade

  • 完整代码

#coding=utf-8
from flask import Flaskfrom flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate,MigrateCommand
from flask_script import Shell,Managerapp = Flask(__name__)
manager = Manager(app)app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:mysql@127.0.0.1:3306/Flask_test'
db = SQLAlchemy(app)#第一个参数是Flask的实例,第二个参数是Sqlalchemy数据库实例
migrate = Migrate(app,db) #manager是Flask-Script的实例,这条语句在flask-Script中添加一个db命令
manager.add_command('db',MigrateCommand)#定义模型Role
class Role(db.Model):# 定义表名__tablename__ = 'roles'# 定义列对象id = db.Column(db.Integer, primary_key=True)name = db.Column(db.String(64), unique=True)user = db.relationship('User', backref='role')#repr()方法显示一个可读字符串,def __repr__(self):return 'Role:'.format(self.name)#定义用户
class User(db.Model):__talbe__ = '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:'.format(self.username)if __name__ == '__main__':manager.run()

  • 命令行迁移命令

  • 初始化迁移文件夹


  • 生成迁移文件


  • 迁移文件


  • 迁移完成后,数据库结果

这里写图片描述


返回之前的版本


  • 可以根据history命令找到版本号,然后传给downgrade命令
  • 找到版本号

python app.py db history


  • 回滚到指定版本

python app.py db downgrade 版本号


  • 注意回滚到之前的版本,再次更新到新的版本,数据可能会丢失,所以尽量避免删除数据,而是去更新数据

邮件扩展


  • 通过Flask_Mail拓展包,可以在Flask程序中发送邮件
  • 原理:Flask-mail连接到简单邮件发送协议(Simple Mail Transfer Protocol,SMTP)服务器 ,并把邮件交给服务器发送

步骤


  • 1 设置邮箱授权码,开启邮箱SMTP服务设置(同django一样)
  • 2 从flask_mail中导入 Mail,Message

from flask_mail import Mail, Message


  • 3 配置邮箱

app.config['MAIL_SERVER'] = "smtp.126.com"
app.config['MAIL_PORT'] = 465
app.config['MAIL_USE_SSL'] = True
app.config['MAIL_USERNAME'] = "huidongpeng@126.com"
app.config['MAIL_PASSWORD'] = "heima666"
app.config['MAIL_DEFAULT_SENDER'] = 'FlaskAdmin'

  • 4 将app与Mail关联,生成邮箱对象

mail = Mail(app)


  • 5 用Message设置邮件发送内容

msg = Message('这是邮件的主题', recipients=['huidongpeng@126.com'],body='This is flask mail')

- 6 发送邮件

mail.send(msg)


  • 完整代码

#coding:utf-8
from flask import Flask
from flask_mail import Mail, Messageapp = Flask(__name__)# 配置邮件:服务器/端口/安全套接字层/邮箱名/授权码
app.config['MAIL_SERVER'] = "smtp.126.com"
app.config['MAIL_PORT'] = 465
app.config['MAIL_USE_SSL'] = True
app.config['MAIL_USERNAME'] = "huidongpeng@126.com"
app.config['MAIL_PASSWORD'] = "heima666"
app.config['MAIL_DEFAULT_SENDER'] = 'FlaskAdmin'mail = Mail(app)@app.route('/')
def hello_world():return '发送邮件'@app.route('/send_mail')
def send_mail():msg = Message('这是邮件的主题', recipients=['huidongpeng@126.com'],body='This is flask mail')mail.send(msg)return '已发送邮件'if __name__ == '__main__':app.run(debug=True)

蓝图


  • 蓝图(BluePrint)是一个存储操作方法的容器。
  • 这些操作方法在Blueprint被注册到应用之后,就可以被调用。Flask可以通过Blueprint来组织URL以及处理请求

  • 属性:

    • 一个应用可以有多个blueprint
    • 可以将一个blueprint注册到任何一个未使用的url下
    • 在一个应用中,一个模块可以注册多次
    • Blueprint可以拥有自己的模板,静态文件或者其他的通用操作方法,并不是必须要实现应用的视图和函数的
    • 在一个应用初始化时,就应该注册要使用的Blueprint
    • blueprint不是一个完整的应用,它不能独立于应用运行,必须要注册到某个应用中

使用蓝图的步骤


  • 1.创建一个蓝图对象

admin=Blueprint('admin',__name__)


  • 2.在这个蓝图对象上进行操作,注册路由,指定静态文件夹,注册模板过滤器

@admin.route('/')
def admin_home():return 'admin_home'

  • 3.在应用对象上注册这个蓝图对象

app.register_blueprint(admin,url\_prefix='/admin')


单元测试


  • 所谓单元测试,就是用代码测试代码
  • 实际上就是一些‘断言’(assert代码)
  • 为什么要进行单元测试?
    • 好的程序必须能经得起各种测试,测试是软件开发中必须且极为重要的步骤。成型的应用,功能很多。程序人员每编写一段代码,完成一个小功能就应该进行相应的测试工作,这种面向功能单一的小模块进行测试的过程称为单元测试。这是每一个合格的程序人员都要掌握的基本技能。

断言方法


  • 类似一个判断语句
    assert expression 'AssertionError'

if not expression: raise AssertionError

  • 常用的断言方法

assertEqual 如果两个值相等,则pass
assertNotEqual 如果两个值不相等,则pass
assertTrue 判断bool值为True,则pass
assertFalse 判断bool值为False,则pass
assertIsNone 不存在,则pass
assertIsNotNone 存在,则pass

单元测试步骤


  • 1 定义一个类,继承自uniyyest.TestCase

import unittest
class TestClass(unitest.TestCase):pass

  • 2 在测试类中,定义两个固定写法的测试方法

import unittest
class TestClass(unittest.TestCase):#该方法会首先执行,方法名为固定写法def setUp(self):pass#该方法会在测试代码执行完后执行,方法名为固定写法def tearDown(self):pass

  • 3 在测试类中,编写测试代码

import unittest
class TestClass(unittest.TestCase):#该方法会首先执行,相当于做测试前的准备工作def setUp(self):pass#该方法会在测试代码执行完后执行,相当于做测试后的扫尾工作def tearDown(self):pass#测试代码def test_app_exists(self):pass

RESTful


  • REST:具象状态传输。一般解释为“表现层状态转换”
  • RETT是设计风格而不是标准。是指客户端和服务器的交互形式。我们需要关注的重点是如何设计REST风格的网络接口。

如何设计符合RESTful风格的API


  • 1.域名
    将api部署在专用域名下:

http://api.example.com

或者将api放在主域名下:

http://www.example.com/api/


  • 2.版本
    将API的版本号放在url中:

http://www.example.com/app/1.0/info
http://www.example.com/app/1.2/info

  • 3.路径
    路径表示API的具体网址。每个网址代表一种资源。 资源作为网址,网址中不能有动词只能有名词,一般名词要与数据库的表名对应。而且名词要使用复数。

错误示例:

http://www.example.com/getGoods
http://www.example.com/listOrders

正确示例:

#获取单个商品http://www.example.com/app/goods/1
#获取所有商品http://www.example.com/app/goods

  • 4.使用标准的HTTP方法

对于资源的具体操作类型,由HTTP动词表示。 常用的HTTP动词有四个。

GET SELECT :从服务器获取资源。
POST CREATE :在服务器新建资源。
PUT UPDATE :在服务器更新资源。
DELETE DELETE :从服务器删除资源。

示例

#获取指定商品的信息GET http://www.example.com/goods/ID#新建商品的信息POST http://www.example.com/goods#更新指定商品的信息PUT http://www.example.com/goods/ID#删除指定商品的信息DELETE http://www.example.com/goods/ID

  • 5.过滤信息
    如果资源数据较多,服务器不能将所有数据一次全部返回给客户端。API应该提供参数,过滤返回结果。 实例:

#指定返回数据的数量http://www.example.com/goods?limit=10
#指定返回数据的开始位置http://www.example.com/goods?offset=10
#指定第几页,以及每页数据的数量http://www.example.com/goods?page=2&per_page=20

  • 6.状态码
    服务器向用户返回的状态码和提示信息,常用的有

0 OK :服务器成功返回用户请求的数据
201 CREATED :用户新建或修改数据成功。
202 Accepted:表示请求已进入后台排队。
400 INVALID REQUEST :用户发出的请求有错误。
401 Unauthorized :用户没有权限。
403 Forbidden :访问被禁止。
404 NOT FOUND :请求针对的是不存在的记录。
406 Not Acceptable :用户请求的的格式不正确。
500 INTERNAL SERVER ERROR :服务器发生错误

  • 7.错误信息
    一般来说,服务器返回的错误信息,以键值对的形式返回。

{error: 'Invalid API KEY'
}

  • 8.响应结果
    针对不同结果,服务器向客户端返回的结果应符合以下规范。

#返回商品列表GET http://www.example.com/goods#返回单个商品GET http://www.example.com/goods/cup#返回新生成的商品POST http://www.example.com/goods#返回一个空文档DELETE http://www.example.com/goods

  • 9 使用链接关联相关的资源
    在返回响应结果时提供链接其他API的方法,使客户端很方便的获取相关联的信息。

  • 10 其他
    服务器返回的数据格式,应该尽量使用JSON,避免使用XML。


推荐阅读
  • 本文介绍了如何在Azure应用服务实例上获取.NetCore 3.0+的支持。作者分享了自己在将代码升级为使用.NET Core 3.0时遇到的问题,并提供了解决方法。文章还介绍了在部署过程中使用Kudu构建的方法,并指出了可能出现的错误。此外,还介绍了开发者应用服务计划和免费产品应用服务计划在不同地区的运行情况。最后,文章指出了当前的.NET SDK不支持目标为.NET Core 3.0的问题,并提供了解决方案。 ... [详细]
  • 安装oracle软件1创建用户组、用户和目录bjdb节点下:[rootnode1]#groupadd-g200oinstall[rootnode1]#groupad ... [详细]
  • 本文介绍了三种方法来实现在Win7系统中显示桌面的快捷方式,包括使用任务栏快速启动栏、运行命令和自己创建快捷方式的方法。具体操作步骤详细说明,并提供了保存图标的路径,方便以后使用。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 本文介绍了使用readlink命令获取文件的完整路径的简单方法,并提供了一个示例命令来打印文件的完整路径。共有28种解决方案可供选择。 ... [详细]
  • tcpdump 4.5.1 crash 深入分析
    tcpdump 4.5.1 crash 深入分析 ... [详细]
  • 俗话说,好记性不如烂笔头,这些东西也都是我Google来的,做个笔记以后自己安装也方便些。因为官方wiki的BeginnersGuide讲的非常好,大部分步骤按照wiki一步一步来就 ... [详细]
  • 本文介绍了在rhel5.5操作系统下搭建网关+LAMP+postfix+dhcp的步骤和配置方法。通过配置dhcp自动分配ip、实现外网访问公司网站、内网收发邮件、内网上网以及SNAT转换等功能。详细介绍了安装dhcp和配置相关文件的步骤,并提供了相关的命令和配置示例。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • REVERT权限切换的操作步骤和注意事项
    本文介绍了在SQL Server中进行REVERT权限切换的操作步骤和注意事项。首先登录到SQL Server,其中包括一个具有很小权限的普通用户和一个系统管理员角色中的成员。然后通过添加Windows登录到SQL Server,并将其添加到AdventureWorks数据库中的用户列表中。最后通过REVERT命令切换权限。在操作过程中需要注意的是,确保登录名和数据库名的正确性,并遵循安全措施,以防止权限泄露和数据损坏。 ... [详细]
  • 本文介绍了pack布局管理器在Perl/Tk中的使用方法及注意事项。通过调用pack()方法,可以控制部件在显示窗口中的位置和大小。同时,本文还提到了在使用pack布局管理器时,应注意将部件分组以便在水平和垂直方向上进行堆放。此外,还介绍了使用Frame部件或Toplevel部件来组织部件在窗口内的方法。最后,本文强调了在使用pack布局管理器时,应避免在中间切换到grid布局管理器,以免造成混乱。 ... [详细]
  • Apache Shiro 身份验证绕过漏洞 (CVE202011989) 详细解析及防范措施
    本文详细解析了Apache Shiro 身份验证绕过漏洞 (CVE202011989) 的原理和影响,并提供了相应的防范措施。Apache Shiro 是一个强大且易用的Java安全框架,常用于执行身份验证、授权、密码和会话管理。在Apache Shiro 1.5.3之前的版本中,与Spring控制器一起使用时,存在特制请求可能导致身份验证绕过的漏洞。本文还介绍了该漏洞的具体细节,并给出了防范该漏洞的建议措施。 ... [详细]
  • Python脚本编写创建输出数据库并添加模型和场数据的方法
    本文介绍了使用Python脚本编写创建输出数据库并添加模型数据和场数据的方法。首先导入相应模块,然后创建输出数据库并添加材料属性、截面、部件实例、分析步和帧、节点和单元等对象。接着向输出数据库中添加场数据和历程数据,本例中只添加了节点位移。最后保存数据库文件并关闭文件。文章还提供了部分代码和Abaqus操作步骤。另外,作者还建立了关于Abaqus的学习交流群,欢迎加入并提问。 ... [详细]
  • 1.脚本功能1)自动替换jar包中的配置文件。2)自动备份老版本的Jar包3)自动判断是初次启动还是更新服务2.脚本准备进入ho ... [详细]
author-avatar
loassde_392
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有